mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-07 07:58:54 +08:00
Handle output sections with more than 0x7fffffff bytes.
* object.h (class Relobj): Change map_to_output_ to output_sections_, and just keep a section pointer. Change all uses. Move comdat group support to Sized_relobj. (Relobj::is_section_specially_mapped): Remove. (Relobj::output_section): Remove poff parameter. Change all callers. (Relobj::output_section_offset): New function. (Relobj::set_section_offset): Rewrite. (Relobj::map_to_output): Remove. (Relobj::output_sections): New function. (Relobj::do_output_section_offset): New pure virtual function. (Relobj::do_set_section_offset): Likewise. (class Sized_relobj): Add section_offsets_ field. Add comdat group support from Relobj. Update declarations. (Sized_relobj::get_output_section_offset): New function. (Sized_relobj::do_output_section_offset): New function. (Sized_relobj::do_set_section_offset): New function. * object.cc (Relobj::output_section_address): Remove. (Sized_relobj::Sized_relobj): Initialize new fields. (Sized_relobj::include_section_group): Cast find_kept_object to Sized_relobj. (Sized_relobj::include_linkonce_section): Likewise. (Sized_relobj::do_layout): Use separate arrays for output section and output offset. (Sized_relobj::do_count_local_symbols): Change map_to_output to output_sections. (Sized_relobj::do_finalize_local_symbols): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_local_symbols): Likewise. (map_to_kept_section): Compute output address directly. * reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to output_sections and section_offsets. (Sized_relobj::write_sections): Likewise. (Sized_relobj::relocate_sections): Likewise. * symtab.cc (sized_finalize_symbol): Use output_section_offset. * output.h (class Output_reloc): Update declarations. Change u2_.relobj to Sized_relobj*. (class Output_data_reloc): Change add functions to use Sized_relobj*. * output.cc (Output_reloc::Output_reloc): Change relobj to Sized_relobj*. (Output_reloc::local_section_offset): Change return type to Elf_Addr. Use get_output_section_offset. (Output_reloc::get_address): Likewise. (Output_section::is_input_address_mapped): Don't call is_section_specially_mapped. (Output_section::output_offset): Likewise. (Output_section::output_address): Likewise. (Output_section::starting_output_address): Likewise. * copy-relocs.cc (Copy_relocs::copy_reloc): Change object parameter to Sized_relobj*. (Copy_relocs::need_copy_reloc): Likewise. (Copy_relocs::save): Likewise. * copy-relocs.h (class Copy_relocs): Update declarations. (class Copy_relocs::Copy_reloc_entry): Change constructor to use Sized_relobj*. Change relobj_ field to Sized_relobj*. * target-reloc.h (relocate_for_relocatable): Change offset_in_output_section type to Elf_Addr. Change code that uses it as well. * layout.cc (Layout::layout): Always set *off. * mapfile.cc (Mapfile::print_input_section): Use output_section_offset. * i386.cc (Target_i386::copy_reloc): Change object parameter to Sized_relobj*. * powerpc.cc (Target_powerpc::copy_reloc): Likewise. * sparc.cc (Target_sparc::copy_reloc): Likewise. * x86_64.cc (Target_x86_64::copy_reloc): Likewise.
This commit is contained in:
@ -1,3 +1,74 @@
|
|||||||
|
2008-07-10 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
Handle output sections with more than 0x7fffffff bytes.
|
||||||
|
* object.h (class Relobj): Change map_to_output_ to
|
||||||
|
output_sections_, and just keep a section pointer. Change all
|
||||||
|
uses. Move comdat group support to Sized_relobj.
|
||||||
|
(Relobj::is_section_specially_mapped): Remove.
|
||||||
|
(Relobj::output_section): Remove poff parameter. Change all
|
||||||
|
callers.
|
||||||
|
(Relobj::output_section_offset): New function.
|
||||||
|
(Relobj::set_section_offset): Rewrite.
|
||||||
|
(Relobj::map_to_output): Remove.
|
||||||
|
(Relobj::output_sections): New function.
|
||||||
|
(Relobj::do_output_section_offset): New pure virtual function.
|
||||||
|
(Relobj::do_set_section_offset): Likewise.
|
||||||
|
(class Sized_relobj): Add section_offsets_ field. Add comdat
|
||||||
|
group support from Relobj. Update declarations.
|
||||||
|
(Sized_relobj::get_output_section_offset): New function.
|
||||||
|
(Sized_relobj::do_output_section_offset): New function.
|
||||||
|
(Sized_relobj::do_set_section_offset): New function.
|
||||||
|
* object.cc (Relobj::output_section_address): Remove.
|
||||||
|
(Sized_relobj::Sized_relobj): Initialize new fields.
|
||||||
|
(Sized_relobj::include_section_group): Cast find_kept_object to
|
||||||
|
Sized_relobj.
|
||||||
|
(Sized_relobj::include_linkonce_section): Likewise.
|
||||||
|
(Sized_relobj::do_layout): Use separate arrays for output section
|
||||||
|
and output offset.
|
||||||
|
(Sized_relobj::do_count_local_symbols): Change map_to_output to
|
||||||
|
output_sections.
|
||||||
|
(Sized_relobj::do_finalize_local_symbols): Change map_to_output to
|
||||||
|
output_sections and section_offsets.
|
||||||
|
(Sized_relobj::write_local_symbols): Likewise.
|
||||||
|
(map_to_kept_section): Compute output address directly.
|
||||||
|
* reloc.cc (Sized_relobj::do_read_relocs): Change map_to_output to
|
||||||
|
output_sections and section_offsets.
|
||||||
|
(Sized_relobj::write_sections): Likewise.
|
||||||
|
(Sized_relobj::relocate_sections): Likewise.
|
||||||
|
* symtab.cc (sized_finalize_symbol): Use output_section_offset.
|
||||||
|
* output.h (class Output_reloc): Update declarations. Change
|
||||||
|
u2_.relobj to Sized_relobj*.
|
||||||
|
(class Output_data_reloc): Change add functions to use
|
||||||
|
Sized_relobj*.
|
||||||
|
* output.cc (Output_reloc::Output_reloc): Change relobj to
|
||||||
|
Sized_relobj*.
|
||||||
|
(Output_reloc::local_section_offset): Change return type to
|
||||||
|
Elf_Addr. Use get_output_section_offset.
|
||||||
|
(Output_reloc::get_address): Likewise.
|
||||||
|
(Output_section::is_input_address_mapped): Don't call
|
||||||
|
is_section_specially_mapped.
|
||||||
|
(Output_section::output_offset): Likewise.
|
||||||
|
(Output_section::output_address): Likewise.
|
||||||
|
(Output_section::starting_output_address): Likewise.
|
||||||
|
* copy-relocs.cc (Copy_relocs::copy_reloc): Change object
|
||||||
|
parameter to Sized_relobj*.
|
||||||
|
(Copy_relocs::need_copy_reloc): Likewise.
|
||||||
|
(Copy_relocs::save): Likewise.
|
||||||
|
* copy-relocs.h (class Copy_relocs): Update declarations.
|
||||||
|
(class Copy_relocs::Copy_reloc_entry): Change constructor to use
|
||||||
|
Sized_relobj*. Change relobj_ field to Sized_relobj*.
|
||||||
|
* target-reloc.h (relocate_for_relocatable): Change
|
||||||
|
offset_in_output_section type to Elf_Addr. Change code that uses
|
||||||
|
it as well.
|
||||||
|
* layout.cc (Layout::layout): Always set *off.
|
||||||
|
* mapfile.cc (Mapfile::print_input_section): Use
|
||||||
|
output_section_offset.
|
||||||
|
* i386.cc (Target_i386::copy_reloc): Change object parameter to
|
||||||
|
Sized_relobj*.
|
||||||
|
* powerpc.cc (Target_powerpc::copy_reloc): Likewise.
|
||||||
|
* sparc.cc (Target_sparc::copy_reloc): Likewise.
|
||||||
|
* x86_64.cc (Target_x86_64::copy_reloc): Likewise.
|
||||||
|
|
||||||
2008-07-03 Ian Lance Taylor <iant@google.com>
|
2008-07-03 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
* layout.cc (Layout::include_section): Do not discard unrecognized
|
* layout.cc (Layout::include_section): Do not discard unrecognized
|
||||||
|
@ -58,7 +58,7 @@ Copy_relocs<sh_type, size, big_endian>::copy_reloc(
|
|||||||
Symbol_table* symtab,
|
Symbol_table* symtab,
|
||||||
Layout* layout,
|
Layout* layout,
|
||||||
Sized_symbol<size>* sym,
|
Sized_symbol<size>* sym,
|
||||||
Relobj* object,
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
Output_section *output_section,
|
Output_section *output_section,
|
||||||
const Reloc& rel,
|
const Reloc& rel,
|
||||||
@ -81,7 +81,7 @@ template<int sh_type, int size, bool big_endian>
|
|||||||
bool
|
bool
|
||||||
Copy_relocs<sh_type, size, big_endian>::need_copy_reloc(
|
Copy_relocs<sh_type, size, big_endian>::need_copy_reloc(
|
||||||
Sized_symbol<size>* sym,
|
Sized_symbol<size>* sym,
|
||||||
Relobj* object,
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx) const
|
unsigned int shndx) const
|
||||||
{
|
{
|
||||||
// FIXME: Handle -z nocopyrelocs.
|
// FIXME: Handle -z nocopyrelocs.
|
||||||
@ -172,7 +172,9 @@ Copy_relocs<sh_type, size, big_endian>::add_copy_reloc(
|
|||||||
|
|
||||||
template<int sh_type, int size, bool big_endian>
|
template<int sh_type, int size, bool big_endian>
|
||||||
void
|
void
|
||||||
Copy_relocs<sh_type, size, big_endian>::save(Symbol* sym, Relobj* object,
|
Copy_relocs<sh_type, size, big_endian>::save(
|
||||||
|
Symbol* sym,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
Output_section* output_section,
|
Output_section* output_section,
|
||||||
const Reloc& rel)
|
const Reloc& rel)
|
||||||
|
@ -65,7 +65,8 @@ class Copy_relocs
|
|||||||
// will wind up. REL is the reloc itself. The Output_data_reloc
|
// will wind up. REL is the reloc itself. The Output_data_reloc
|
||||||
// section is where the dynamic relocs are put.
|
// section is where the dynamic relocs are put.
|
||||||
void
|
void
|
||||||
copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>* sym, Relobj* object,
|
copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>* sym,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx, Output_section* output_section,
|
unsigned int shndx, Output_section* output_section,
|
||||||
const Reloc& rel,
|
const Reloc& rel,
|
||||||
Output_data_reloc<sh_type, true, size, big_endian>*);
|
Output_data_reloc<sh_type, true, size, big_endian>*);
|
||||||
@ -91,7 +92,8 @@ class Copy_relocs
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
|
Copy_reloc_entry(Symbol* sym, unsigned int reloc_type,
|
||||||
Relobj* relobj, unsigned int shndx,
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
|
unsigned int shndx,
|
||||||
Output_section* output_section,
|
Output_section* output_section,
|
||||||
Address address, Addend addend)
|
Address address, Addend addend)
|
||||||
: sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
|
: sym_(sym), reloc_type_(reloc_type), relobj_(relobj),
|
||||||
@ -108,7 +110,7 @@ class Copy_relocs
|
|||||||
private:
|
private:
|
||||||
Symbol* sym_;
|
Symbol* sym_;
|
||||||
unsigned int reloc_type_;
|
unsigned int reloc_type_;
|
||||||
Relobj* relobj_;
|
Sized_relobj<size, big_endian>* relobj_;
|
||||||
unsigned int shndx_;
|
unsigned int shndx_;
|
||||||
Output_section* output_section_;
|
Output_section* output_section_;
|
||||||
Address address_;
|
Address address_;
|
||||||
@ -120,7 +122,8 @@ class Copy_relocs
|
|||||||
|
|
||||||
// Return whether we need a COPY reloc.
|
// Return whether we need a COPY reloc.
|
||||||
bool
|
bool
|
||||||
need_copy_reloc(Sized_symbol<size>* gsym, Relobj* object,
|
need_copy_reloc(Sized_symbol<size>* gsym,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx) const;
|
unsigned int shndx) const;
|
||||||
|
|
||||||
// Emit a COPY reloc.
|
// Emit a COPY reloc.
|
||||||
@ -135,8 +138,8 @@ class Copy_relocs
|
|||||||
|
|
||||||
// Save a reloc against SYM for possible emission later.
|
// Save a reloc against SYM for possible emission later.
|
||||||
void
|
void
|
||||||
save(Symbol*, Relobj*, unsigned int shndx, Output_section*,
|
save(Symbol*, Sized_relobj<size, big_endian>*, unsigned int shndx,
|
||||||
const Reloc& rel);
|
Output_section*, const Reloc& rel);
|
||||||
|
|
||||||
// The target specific relocation type of the COPY relocation.
|
// The target specific relocation type of the COPY relocation.
|
||||||
const unsigned int copy_reloc_type_;
|
const unsigned int copy_reloc_type_;
|
||||||
|
@ -357,7 +357,8 @@ class Target_i386 : public Sized_target<32, false>
|
|||||||
|
|
||||||
// Add a potential copy relocation.
|
// Add a potential copy relocation.
|
||||||
void
|
void
|
||||||
copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
|
copy_reloc(Symbol_table* symtab, Layout* layout,
|
||||||
|
Sized_relobj<32, false>* object,
|
||||||
unsigned int shndx, Output_section* output_section,
|
unsigned int shndx, Output_section* output_section,
|
||||||
Symbol* sym, const elfcpp::Rel<32, false>& reloc)
|
Symbol* sym, const elfcpp::Rel<32, false>& reloc)
|
||||||
{
|
{
|
||||||
|
@ -448,6 +448,8 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
|
|||||||
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
const char* name, const elfcpp::Shdr<size, big_endian>& shdr,
|
||||||
unsigned int reloc_shndx, unsigned int, off_t* off)
|
unsigned int reloc_shndx, unsigned int, off_t* off)
|
||||||
{
|
{
|
||||||
|
*off = 0;
|
||||||
|
|
||||||
if (!this->include_section(object, name, shdr))
|
if (!this->include_section(object, name, shdr))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -256,12 +256,10 @@ Mapfile::print_input_section(Relobj* relobj, unsigned int shndx)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
section_offset_type offset;
|
os = relobj->output_section(shndx);
|
||||||
os = relobj->output_section(shndx, &offset);
|
addr = relobj->output_section_offset(shndx);
|
||||||
if (offset == -1)
|
if (addr != -1U)
|
||||||
addr = ~0ULL;
|
addr += os->address();
|
||||||
else
|
|
||||||
addr = os->address() + offset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char sizebuf[50];
|
char sizebuf[50];
|
||||||
|
@ -38,7 +38,7 @@ class Merge_map;
|
|||||||
// For each object with merge sections, we store an Object_merge_map.
|
// For each object with merge sections, we store an Object_merge_map.
|
||||||
// This is used to map locations in input sections to a merged output
|
// This is used to map locations in input sections to a merged output
|
||||||
// section. The output section itself is not recorded here--it can be
|
// section. The output section itself is not recorded here--it can be
|
||||||
// found in the map_to_output_ field of the Object.
|
// found in the output_sections_ field of the Object.
|
||||||
|
|
||||||
class Object_merge_map
|
class Object_merge_map
|
||||||
{
|
{
|
||||||
|
@ -230,18 +230,6 @@ Object::handle_gnu_warning_section(const char* name, unsigned int shndx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Class Relobj.
|
|
||||||
|
|
||||||
// Return the output address of the input section SHNDX.
|
|
||||||
uint64_t
|
|
||||||
Relobj::output_section_address(unsigned int shndx) const
|
|
||||||
{
|
|
||||||
section_offset_type offset;
|
|
||||||
Output_section* os = this->output_section(shndx, &offset);
|
|
||||||
gold_assert(os != NULL && offset != -1);
|
|
||||||
return os->address() + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Class Sized_relobj.
|
// Class Sized_relobj.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
@ -261,6 +249,8 @@ Sized_relobj<size, big_endian>::Sized_relobj(
|
|||||||
local_dynsym_offset_(0),
|
local_dynsym_offset_(0),
|
||||||
local_values_(),
|
local_values_(),
|
||||||
local_got_offsets_(),
|
local_got_offsets_(),
|
||||||
|
kept_comdat_sections_(),
|
||||||
|
comdat_groups_(),
|
||||||
has_eh_frame_(false)
|
has_eh_frame_(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -610,7 +600,7 @@ Sized_relobj<size, big_endian>::include_section_group(
|
|||||||
bool include_group = ((flags & elfcpp::GRP_COMDAT) == 0
|
bool include_group = ((flags & elfcpp::GRP_COMDAT) == 0
|
||||||
|| layout->add_comdat(this, index, signature, true));
|
|| layout->add_comdat(this, index, signature, true));
|
||||||
|
|
||||||
Relobj* kept_object = NULL;
|
Sized_relobj<size, big_endian>* kept_object = NULL;
|
||||||
Comdat_group* kept_group = NULL;
|
Comdat_group* kept_group = NULL;
|
||||||
|
|
||||||
if (!include_group)
|
if (!include_group)
|
||||||
@ -618,7 +608,9 @@ Sized_relobj<size, big_endian>::include_section_group(
|
|||||||
// This group is being discarded. Find the object and group
|
// This group is being discarded. Find the object and group
|
||||||
// that was kept in its place.
|
// that was kept in its place.
|
||||||
unsigned int kept_group_index = 0;
|
unsigned int kept_group_index = 0;
|
||||||
kept_object = layout->find_kept_object(signature, &kept_group_index);
|
Relobj* kept_relobj = layout->find_kept_object(signature,
|
||||||
|
&kept_group_index);
|
||||||
|
kept_object = static_cast<Sized_relobj<size, big_endian>*>(kept_relobj);
|
||||||
if (kept_object != NULL)
|
if (kept_object != NULL)
|
||||||
kept_group = kept_object->find_comdat_group(kept_group_index);
|
kept_group = kept_object->find_comdat_group(kept_group_index);
|
||||||
}
|
}
|
||||||
@ -749,9 +741,11 @@ Sized_relobj<size, big_endian>::include_linkonce_section(
|
|||||||
// In this case, the section index stored with the layout object
|
// In this case, the section index stored with the layout object
|
||||||
// is the linkonce section that was kept.
|
// is the linkonce section that was kept.
|
||||||
unsigned int kept_group_index = 0;
|
unsigned int kept_group_index = 0;
|
||||||
Relobj* kept_object = layout->find_kept_object(sig2, &kept_group_index);
|
Relobj* kept_relobj = layout->find_kept_object(sig2, &kept_group_index);
|
||||||
if (kept_object != NULL)
|
if (kept_relobj != NULL)
|
||||||
{
|
{
|
||||||
|
Sized_relobj<size, big_endian>* kept_object
|
||||||
|
= static_cast<Sized_relobj<size, big_endian>*>(kept_relobj);
|
||||||
Kept_comdat_section* kept =
|
Kept_comdat_section* kept =
|
||||||
new Kept_comdat_section(kept_object, kept_group_index);
|
new Kept_comdat_section(kept_object, kept_group_index);
|
||||||
this->set_kept_comdat_section(index, kept);
|
this->set_kept_comdat_section(index, kept);
|
||||||
@ -767,9 +761,11 @@ Sized_relobj<size, big_endian>::include_linkonce_section(
|
|||||||
// the group has only one member section. Otherwise, it's not
|
// the group has only one member section. Otherwise, it's not
|
||||||
// worth the effort.
|
// worth the effort.
|
||||||
unsigned int kept_group_index = 0;
|
unsigned int kept_group_index = 0;
|
||||||
Relobj* kept_object = layout->find_kept_object(sig1, &kept_group_index);
|
Relobj* kept_relobj = layout->find_kept_object(sig1, &kept_group_index);
|
||||||
if (kept_object != NULL)
|
if (kept_relobj != NULL)
|
||||||
{
|
{
|
||||||
|
Sized_relobj<size, big_endian>* kept_object =
|
||||||
|
static_cast<Sized_relobj<size, big_endian>*>(kept_relobj);
|
||||||
Comdat_group* kept_group =
|
Comdat_group* kept_group =
|
||||||
kept_object->find_comdat_group(kept_group_index);
|
kept_object->find_comdat_group(kept_group_index);
|
||||||
if (kept_group != NULL && kept_group->size() == 1)
|
if (kept_group != NULL && kept_group->size() == 1)
|
||||||
@ -841,8 +837,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Map_to_output>& map_sections(this->map_to_output());
|
Output_sections& out_sections(this->output_sections());
|
||||||
map_sections.resize(shnum);
|
std::vector<Address>& out_section_offsets(this->section_offsets_);
|
||||||
|
|
||||||
|
out_sections.resize(shnum);
|
||||||
|
out_section_offsets.resize(shnum);
|
||||||
|
|
||||||
// If we are only linking for symbols, then there is nothing else to
|
// If we are only linking for symbols, then there is nothing else to
|
||||||
// do here.
|
// do here.
|
||||||
@ -924,7 +923,8 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
if (discard)
|
if (discard)
|
||||||
{
|
{
|
||||||
// Do not include this section in the link.
|
// Do not include this section in the link.
|
||||||
map_sections[i].output_section = NULL;
|
out_sections[i] = NULL;
|
||||||
|
out_section_offsets[i] = -1U;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,8 +963,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
reloc_shndx[i], reloc_type[i],
|
reloc_shndx[i], reloc_type[i],
|
||||||
&offset);
|
&offset);
|
||||||
|
|
||||||
map_sections[i].output_section = os;
|
out_sections[i] = os;
|
||||||
map_sections[i].offset = offset;
|
if (offset == -1)
|
||||||
|
out_section_offsets[i] = -1U;
|
||||||
|
else
|
||||||
|
out_section_offsets[i] = convert_types<Address, off_t>(offset);
|
||||||
|
|
||||||
// If this section requires special handling, and if there are
|
// If this section requires special handling, and if there are
|
||||||
// relocs that apply to it, then we must do the special handling
|
// relocs that apply to it, then we must do the special handling
|
||||||
@ -995,10 +998,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output_section* data_section = map_sections[data_shndx].output_section;
|
Output_section* data_section = out_sections[data_shndx];
|
||||||
if (data_section == NULL)
|
if (data_section == NULL)
|
||||||
{
|
{
|
||||||
map_sections[i].output_section = NULL;
|
out_sections[i] = NULL;
|
||||||
|
out_section_offsets[i] = -1U;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,8 +1011,8 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
|
|
||||||
Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
|
Output_section* os = layout->layout_reloc(this, i, shdr, data_section,
|
||||||
rr);
|
rr);
|
||||||
map_sections[i].output_section = os;
|
out_sections[i] = os;
|
||||||
map_sections[i].offset = -1;
|
out_section_offsets[i] = -1U;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the .eh_frame sections at the end.
|
// Handle the .eh_frame sections at the end.
|
||||||
@ -1034,8 +1038,11 @@ Sized_relobj<size, big_endian>::do_layout(Symbol_table* symtab,
|
|||||||
reloc_shndx[i],
|
reloc_shndx[i],
|
||||||
reloc_type[i],
|
reloc_type[i],
|
||||||
&offset);
|
&offset);
|
||||||
map_sections[i].output_section = os;
|
out_sections[i] = os;
|
||||||
map_sections[i].offset = offset;
|
if (offset == -1)
|
||||||
|
out_section_offsets[i] = -1U;
|
||||||
|
else
|
||||||
|
out_section_offsets[i] = convert_types<Address, off_t>(offset);
|
||||||
|
|
||||||
// If this section requires special handling, and if there are
|
// If this section requires special handling, and if there are
|
||||||
// relocs that apply to it, then we must do the special handling
|
// relocs that apply to it, then we must do the special handling
|
||||||
@ -1131,7 +1138,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
|
|||||||
|
|
||||||
// Loop over the local symbols.
|
// Loop over the local symbols.
|
||||||
|
|
||||||
const std::vector<Map_to_output>& mo(this->map_to_output());
|
const Output_sections& out_sections(this->output_sections());
|
||||||
unsigned int shnum = this->shnum();
|
unsigned int shnum = this->shnum();
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
unsigned int dyncount = 0;
|
unsigned int dyncount = 0;
|
||||||
@ -1158,7 +1165,7 @@ Sized_relobj<size, big_endian>::do_count_local_symbols(Stringpool* pool,
|
|||||||
|
|
||||||
// Decide whether this symbol should go into the output file.
|
// Decide whether this symbol should go into the output file.
|
||||||
|
|
||||||
if (shndx < shnum && mo[shndx].output_section == NULL)
|
if (shndx < shnum && out_sections[shndx] == NULL)
|
||||||
{
|
{
|
||||||
lv.set_no_output_symtab_entry();
|
lv.set_no_output_symtab_entry();
|
||||||
gold_assert(!lv.needs_output_dynsym_entry());
|
gold_assert(!lv.needs_output_dynsym_entry());
|
||||||
@ -1213,7 +1220,8 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
|
|||||||
const unsigned int loccount = this->local_symbol_count_;
|
const unsigned int loccount = this->local_symbol_count_;
|
||||||
this->local_symbol_offset_ = off;
|
this->local_symbol_offset_ = off;
|
||||||
|
|
||||||
const std::vector<Map_to_output>& mo(this->map_to_output());
|
const Output_sections& out_sections(this->output_sections());
|
||||||
|
const std::vector<Address>& out_offsets(this->section_offsets_);
|
||||||
unsigned int shnum = this->shnum();
|
unsigned int shnum = this->shnum();
|
||||||
|
|
||||||
for (unsigned int i = 1; i < loccount; ++i)
|
for (unsigned int i = 1; i < loccount; ++i)
|
||||||
@ -1245,7 +1253,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
|
|||||||
shndx = 0;
|
shndx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output_section* os = mo[shndx].output_section;
|
Output_section* os = out_sections[shndx];
|
||||||
|
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
{
|
{
|
||||||
@ -1255,7 +1263,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
|
|||||||
// so we leave the input value unchanged here.
|
// so we leave the input value unchanged here.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (mo[shndx].offset == -1)
|
else if (out_offsets[shndx] == -1U)
|
||||||
{
|
{
|
||||||
// This is a SHF_MERGE section or one which otherwise
|
// This is a SHF_MERGE section or one which otherwise
|
||||||
// requires special handling. We get the output address
|
// requires special handling. We get the output address
|
||||||
@ -1278,11 +1286,11 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
|
|||||||
}
|
}
|
||||||
else if (lv.is_tls_symbol())
|
else if (lv.is_tls_symbol())
|
||||||
lv.set_output_value(os->tls_offset()
|
lv.set_output_value(os->tls_offset()
|
||||||
+ mo[shndx].offset
|
+ out_offsets[shndx]
|
||||||
+ lv.input_value());
|
+ lv.input_value());
|
||||||
else
|
else
|
||||||
lv.set_output_value(os->address()
|
lv.set_output_value(os->address()
|
||||||
+ mo[shndx].offset
|
+ out_offsets[shndx]
|
||||||
+ lv.input_value());
|
+ lv.input_value());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1385,7 +1393,7 @@ Sized_relobj<size, big_endian>::write_local_symbols(
|
|||||||
dyn_oview = of->get_output_view(this->local_dynsym_offset_,
|
dyn_oview = of->get_output_view(this->local_dynsym_offset_,
|
||||||
dyn_output_size);
|
dyn_output_size);
|
||||||
|
|
||||||
const std::vector<Map_to_output>& mo(this->map_to_output());
|
const Output_sections out_sections(this->output_sections());
|
||||||
|
|
||||||
gold_assert(this->local_values_.size() == loccount);
|
gold_assert(this->local_values_.size() == loccount);
|
||||||
|
|
||||||
@ -1403,10 +1411,10 @@ Sized_relobj<size, big_endian>::write_local_symbols(
|
|||||||
&is_ordinary);
|
&is_ordinary);
|
||||||
if (is_ordinary)
|
if (is_ordinary)
|
||||||
{
|
{
|
||||||
gold_assert(st_shndx < mo.size());
|
gold_assert(st_shndx < out_sections.size());
|
||||||
if (mo[st_shndx].output_section == NULL)
|
if (out_sections[st_shndx] == NULL)
|
||||||
continue;
|
continue;
|
||||||
st_shndx = mo[st_shndx].output_section->out_shndx();
|
st_shndx = out_sections[st_shndx]->out_shndx();
|
||||||
if (st_shndx >= elfcpp::SHN_LORESERVE)
|
if (st_shndx >= elfcpp::SHN_LORESERVE)
|
||||||
{
|
{
|
||||||
if (lv.needs_output_symtab_entry())
|
if (lv.needs_output_symtab_entry())
|
||||||
@ -1560,8 +1568,10 @@ Sized_relobj<size, big_endian>::map_to_kept_section(
|
|||||||
{
|
{
|
||||||
gold_assert(kept->object_ != NULL);
|
gold_assert(kept->object_ != NULL);
|
||||||
*found = true;
|
*found = true;
|
||||||
return (static_cast<Address>
|
Output_section* os = kept->object_->output_section(kept->shndx_);
|
||||||
(kept->object_->output_section_address(kept->shndx_)));
|
Address offset = kept->object_->get_output_section_offset(kept->shndx_);
|
||||||
|
gold_assert(os != NULL && offset != -1U);
|
||||||
|
return os->address() + offset;
|
||||||
}
|
}
|
||||||
*found = false;
|
*found = false;
|
||||||
return 0;
|
return 0;
|
||||||
|
255
gold/object.h
255
gold/object.h
@ -560,9 +560,7 @@ class Relobj : public Object
|
|||||||
public:
|
public:
|
||||||
Relobj(const std::string& name, Input_file* input_file, off_t offset = 0)
|
Relobj(const std::string& name, Input_file* input_file, off_t offset = 0)
|
||||||
: Object(name, input_file, false, offset),
|
: Object(name, input_file, false, offset),
|
||||||
map_to_output_(),
|
output_sections_(),
|
||||||
comdat_groups_(),
|
|
||||||
kept_comdat_sections_(),
|
|
||||||
map_to_relocatable_relocs_(NULL),
|
map_to_relocatable_relocs_(NULL),
|
||||||
object_merge_map_(NULL),
|
object_merge_map_(NULL),
|
||||||
relocs_must_follow_section_writes_(false)
|
relocs_must_follow_section_writes_(false)
|
||||||
@ -619,39 +617,31 @@ class Relobj : public Object
|
|||||||
bool
|
bool
|
||||||
is_section_included(unsigned int shndx) const
|
is_section_included(unsigned int shndx) const
|
||||||
{
|
{
|
||||||
gold_assert(shndx < this->map_to_output_.size());
|
gold_assert(shndx < this->output_sections_.size());
|
||||||
return this->map_to_output_[shndx].output_section != NULL;
|
return this->output_sections_[shndx] != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return whether an input section requires special
|
// Given a section index, return the corresponding Output_section.
|
||||||
// handling--whether it is not simply mapped from the input file to
|
// The return value will be NULL if the section is not included in
|
||||||
// the output file.
|
// the link.
|
||||||
bool
|
Output_section*
|
||||||
is_section_specially_mapped(unsigned int shndx) const
|
output_section(unsigned int shndx) const
|
||||||
{
|
{
|
||||||
gold_assert(shndx < this->map_to_output_.size());
|
gold_assert(shndx < this->output_sections_.size());
|
||||||
return (this->map_to_output_[shndx].output_section != NULL
|
return this->output_sections_[shndx];
|
||||||
&& this->map_to_output_[shndx].offset == -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Given a section index, return the corresponding Output_section
|
// Given a section index, return the offset in the Output_section.
|
||||||
// (which will be NULL if the section is not included in the link)
|
// The return value will be -1U if the section is specially mapped,
|
||||||
// and set *POFF to the offset within that section. *POFF will be
|
// such as a merge section.
|
||||||
// set to -1 if the section requires special handling.
|
uint64_t
|
||||||
inline Output_section*
|
output_section_offset(unsigned int shndx) const
|
||||||
output_section(unsigned int shndx, section_offset_type* poff) const;
|
{ return this->do_output_section_offset(shndx); }
|
||||||
|
|
||||||
// Set the offset of an input section within its output section.
|
// Set the offset of an input section within its output section.
|
||||||
void
|
virtual void
|
||||||
set_section_offset(unsigned int shndx, section_offset_type off)
|
set_section_offset(unsigned int shndx, uint64_t off)
|
||||||
{
|
{ this->do_set_section_offset(shndx, off); }
|
||||||
gold_assert(shndx < this->map_to_output_.size());
|
|
||||||
this->map_to_output_[shndx].offset = off;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the output address of the input section SHNDX.
|
|
||||||
uint64_t
|
|
||||||
output_section_address(unsigned int shndx) const;
|
|
||||||
|
|
||||||
// Return true if we need to wait for output sections to be written
|
// Return true if we need to wait for output sections to be written
|
||||||
// before we can apply relocations. This is true if the object has
|
// before we can apply relocations. This is true if the object has
|
||||||
@ -690,54 +680,11 @@ class Relobj : public Object
|
|||||||
return (*this->map_to_relocatable_relocs_)[reloc_shndx];
|
return (*this->map_to_relocatable_relocs_)[reloc_shndx];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Information needed to keep track of kept comdat groups. This is
|
|
||||||
// simply a map from the section name to its section index. This may
|
|
||||||
// not be a one-to-one mapping, but we ignore that possibility since
|
|
||||||
// this is used only to attempt to handle stray relocations from
|
|
||||||
// non-comdat debug sections that refer to comdat loadable sections.
|
|
||||||
typedef Unordered_map<std::string, unsigned int> Comdat_group;
|
|
||||||
|
|
||||||
// Find a comdat group table given its group section SHNDX.
|
|
||||||
Comdat_group*
|
|
||||||
find_comdat_group(unsigned int shndx) const
|
|
||||||
{
|
|
||||||
Comdat_group_table::const_iterator p =
|
|
||||||
this->comdat_groups_.find(shndx);
|
|
||||||
if (p != this->comdat_groups_.end())
|
|
||||||
return p->second;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// What we need to know to map an input section to an output
|
// The output section to be used for each input section, indexed by
|
||||||
// section. We keep an array of these, one for each input section,
|
// the input section number. The output section is NULL if the
|
||||||
// indexed by the input section number.
|
// input section is to be discarded.
|
||||||
struct Map_to_output
|
typedef std::vector<Output_section*> Output_sections;
|
||||||
{
|
|
||||||
// The output section. This is NULL if the input section is to be
|
|
||||||
// discarded.
|
|
||||||
Output_section* output_section;
|
|
||||||
// The offset within the output section. This is -1 if the
|
|
||||||
// section requires special handling.
|
|
||||||
section_offset_type offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A map from group section index to the table of group members.
|
|
||||||
typedef std::map<unsigned int, Comdat_group*> Comdat_group_table;
|
|
||||||
|
|
||||||
// To keep track of discarded comdat sections, we need to map a member
|
|
||||||
// section index to the object and section index of the corresponding
|
|
||||||
// kept section.
|
|
||||||
struct Kept_comdat_section
|
|
||||||
{
|
|
||||||
Kept_comdat_section(Relobj* object, unsigned int shndx)
|
|
||||||
: object_(object), shndx_(shndx)
|
|
||||||
{ }
|
|
||||||
Relobj* object_;
|
|
||||||
unsigned int shndx_;
|
|
||||||
};
|
|
||||||
typedef std::map<unsigned int, Kept_comdat_section*>
|
|
||||||
Kept_comdat_section_table;
|
|
||||||
|
|
||||||
// Read the relocs--implemented by child class.
|
// Read the relocs--implemented by child class.
|
||||||
virtual void
|
virtual void
|
||||||
@ -777,38 +724,22 @@ class Relobj : public Object
|
|||||||
do_relocate(const General_options& options, const Symbol_table* symtab,
|
do_relocate(const General_options& options, const Symbol_table* symtab,
|
||||||
const Layout*, Output_file* of) = 0;
|
const Layout*, Output_file* of) = 0;
|
||||||
|
|
||||||
|
// Get the offset of a section--implemented by child class.
|
||||||
|
virtual uint64_t
|
||||||
|
do_output_section_offset(unsigned int shndx) const = 0;
|
||||||
|
|
||||||
|
// Set the offset of a section--implemented by child class.
|
||||||
|
virtual void
|
||||||
|
do_set_section_offset(unsigned int shndx, uint64_t off) = 0;
|
||||||
|
|
||||||
// Return the vector mapping input sections to output sections.
|
// Return the vector mapping input sections to output sections.
|
||||||
std::vector<Map_to_output>&
|
Output_sections&
|
||||||
map_to_output()
|
output_sections()
|
||||||
{ return this->map_to_output_; }
|
{ return this->output_sections_; }
|
||||||
|
|
||||||
const std::vector<Map_to_output>&
|
const Output_sections&
|
||||||
map_to_output() const
|
output_sections() const
|
||||||
{ return this->map_to_output_; }
|
{ return this->output_sections_; }
|
||||||
|
|
||||||
// Record a new comdat group whose group section index is SHNDX.
|
|
||||||
void
|
|
||||||
add_comdat_group(unsigned int shndx, Comdat_group* group)
|
|
||||||
{ this->comdat_groups_[shndx] = group; }
|
|
||||||
|
|
||||||
// Record a mapping from discarded section SHNDX to the corresponding
|
|
||||||
// kept section.
|
|
||||||
void
|
|
||||||
set_kept_comdat_section(unsigned int shndx, Kept_comdat_section* kept)
|
|
||||||
{
|
|
||||||
this->kept_comdat_sections_[shndx] = kept;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the kept section corresponding to the discarded section SHNDX.
|
|
||||||
Kept_comdat_section*
|
|
||||||
get_kept_comdat_section(unsigned int shndx) const
|
|
||||||
{
|
|
||||||
Kept_comdat_section_table::const_iterator p =
|
|
||||||
this->kept_comdat_sections_.find(shndx);
|
|
||||||
if (p == this->kept_comdat_sections_.end())
|
|
||||||
return NULL;
|
|
||||||
return p->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the size of the relocatable relocs array.
|
// Set the size of the relocatable relocs array.
|
||||||
void
|
void
|
||||||
@ -826,11 +757,7 @@ class Relobj : public Object
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Mapping from input sections to output section.
|
// Mapping from input sections to output section.
|
||||||
std::vector<Map_to_output> map_to_output_;
|
Output_sections output_sections_;
|
||||||
// Table of kept comdat groups.
|
|
||||||
Comdat_group_table comdat_groups_;
|
|
||||||
// Table mapping discarded comdat sections to corresponding kept sections.
|
|
||||||
Kept_comdat_section_table kept_comdat_sections_;
|
|
||||||
// Mapping from input section index to the information recorded for
|
// Mapping from input section index to the information recorded for
|
||||||
// the relocations. This is only used for a relocatable link.
|
// the relocations. This is only used for a relocatable link.
|
||||||
std::vector<Relocatable_relocs*>* map_to_relocatable_relocs_;
|
std::vector<Relocatable_relocs*>* map_to_relocatable_relocs_;
|
||||||
@ -842,16 +769,6 @@ class Relobj : public Object
|
|||||||
bool relocs_must_follow_section_writes_;
|
bool relocs_must_follow_section_writes_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Implement Object::output_section inline for efficiency.
|
|
||||||
inline Output_section*
|
|
||||||
Relobj::output_section(unsigned int shndx, section_offset_type* poff) const
|
|
||||||
{
|
|
||||||
gold_assert(shndx < this->map_to_output_.size());
|
|
||||||
const Map_to_output& mo(this->map_to_output_[shndx]);
|
|
||||||
*poff = mo.offset;
|
|
||||||
return mo.output_section;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This class is used to handle relocations against a section symbol
|
// This class is used to handle relocations against a section symbol
|
||||||
// in an SHF_MERGE section. For such a symbol, we need to know the
|
// in an SHF_MERGE section. For such a symbol, we need to know the
|
||||||
// addend of the relocation before we can determine the final value.
|
// addend of the relocation before we can determine the final value.
|
||||||
@ -1356,6 +1273,17 @@ class Sized_relobj : public Relobj
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the offset of input section SHNDX within its output section.
|
||||||
|
// This is -1 if the input section requires a special mapping, such
|
||||||
|
// as a merge section. The output section can be found in the
|
||||||
|
// output_sections_ field of the parent class Relobj.
|
||||||
|
Address
|
||||||
|
get_output_section_offset(unsigned int shndx) const
|
||||||
|
{
|
||||||
|
gold_assert(shndx < this->section_offsets_.size());
|
||||||
|
return this->section_offsets_[shndx];
|
||||||
|
}
|
||||||
|
|
||||||
// Return the name of the symbol that spans the given offset in the
|
// Return the name of the symbol that spans the given offset in the
|
||||||
// specified section in this object. This is used only for error
|
// specified section in this object. This is used only for error
|
||||||
// messages and is not particularly efficient.
|
// messages and is not particularly efficient.
|
||||||
@ -1467,6 +1395,19 @@ class Sized_relobj : public Relobj
|
|||||||
Xindex*
|
Xindex*
|
||||||
do_initialize_xindex();
|
do_initialize_xindex();
|
||||||
|
|
||||||
|
// Get the offset of a section.
|
||||||
|
uint64_t
|
||||||
|
do_output_section_offset(unsigned int shndx) const
|
||||||
|
{ return this->get_output_section_offset(shndx); }
|
||||||
|
|
||||||
|
// Set the offset of a section.
|
||||||
|
void
|
||||||
|
do_set_section_offset(unsigned int shndx, uint64_t off)
|
||||||
|
{
|
||||||
|
gold_assert(shndx < this->section_offsets_.size());
|
||||||
|
this->section_offsets_[shndx] = convert_types<Address, uint64_t>(off);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For convenience.
|
// For convenience.
|
||||||
typedef Sized_relobj<size, big_endian> This;
|
typedef Sized_relobj<size, big_endian> This;
|
||||||
@ -1475,6 +1416,47 @@ class Sized_relobj : public Relobj
|
|||||||
static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
static const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||||
typedef elfcpp::Shdr<size, big_endian> Shdr;
|
typedef elfcpp::Shdr<size, big_endian> Shdr;
|
||||||
|
|
||||||
|
// To keep track of discarded comdat sections, we need to map a member
|
||||||
|
// section index to the object and section index of the corresponding
|
||||||
|
// kept section.
|
||||||
|
struct Kept_comdat_section
|
||||||
|
{
|
||||||
|
Kept_comdat_section(Sized_relobj<size, big_endian>* object,
|
||||||
|
unsigned int shndx)
|
||||||
|
: object_(object), shndx_(shndx)
|
||||||
|
{ }
|
||||||
|
Sized_relobj<size, big_endian>* object_;
|
||||||
|
unsigned int shndx_;
|
||||||
|
};
|
||||||
|
typedef std::map<unsigned int, Kept_comdat_section*>
|
||||||
|
Kept_comdat_section_table;
|
||||||
|
|
||||||
|
// Information needed to keep track of kept comdat groups. This is
|
||||||
|
// simply a map from the section name to its section index. This may
|
||||||
|
// not be a one-to-one mapping, but we ignore that possibility since
|
||||||
|
// this is used only to attempt to handle stray relocations from
|
||||||
|
// non-comdat debug sections that refer to comdat loadable sections.
|
||||||
|
typedef Unordered_map<std::string, unsigned int> Comdat_group;
|
||||||
|
|
||||||
|
// A map from group section index to the table of group members.
|
||||||
|
typedef std::map<unsigned int, Comdat_group*> Comdat_group_table;
|
||||||
|
|
||||||
|
// Find a comdat group table given its group section SHNDX.
|
||||||
|
Comdat_group*
|
||||||
|
find_comdat_group(unsigned int shndx) const
|
||||||
|
{
|
||||||
|
Comdat_group_table::const_iterator p =
|
||||||
|
this->comdat_groups_.find(shndx);
|
||||||
|
if (p != this->comdat_groups_.end())
|
||||||
|
return p->second;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record a new comdat group whose group section index is SHNDX.
|
||||||
|
void
|
||||||
|
add_comdat_group(unsigned int shndx, Comdat_group* group)
|
||||||
|
{ this->comdat_groups_[shndx] = group; }
|
||||||
|
|
||||||
// Adjust a section index if necessary.
|
// Adjust a section index if necessary.
|
||||||
unsigned int
|
unsigned int
|
||||||
adjust_shndx(unsigned int shndx)
|
adjust_shndx(unsigned int shndx)
|
||||||
@ -1552,7 +1534,7 @@ class Sized_relobj : public Relobj
|
|||||||
void
|
void
|
||||||
emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
|
emit_relocs(const Relocate_info<size, big_endian>*, unsigned int,
|
||||||
unsigned int sh_type, const unsigned char* prelocs,
|
unsigned int sh_type, const unsigned char* prelocs,
|
||||||
size_t reloc_count, Output_section*, off_t output_offset,
|
size_t reloc_count, Output_section*, Address output_offset,
|
||||||
unsigned char* view, Address address,
|
unsigned char* view, Address address,
|
||||||
section_size_type view_size,
|
section_size_type view_size,
|
||||||
unsigned char* reloc_view, section_size_type reloc_view_size);
|
unsigned char* reloc_view, section_size_type reloc_view_size);
|
||||||
@ -1563,7 +1545,7 @@ class Sized_relobj : public Relobj
|
|||||||
void
|
void
|
||||||
emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
|
emit_relocs_reltype(const Relocate_info<size, big_endian>*, unsigned int,
|
||||||
const unsigned char* prelocs, size_t reloc_count,
|
const unsigned char* prelocs, size_t reloc_count,
|
||||||
Output_section*, off_t output_offset,
|
Output_section*, Address output_offset,
|
||||||
unsigned char* view, Address address,
|
unsigned char* view, Address address,
|
||||||
section_size_type view_size,
|
section_size_type view_size,
|
||||||
unsigned char* reloc_view,
|
unsigned char* reloc_view,
|
||||||
@ -1595,6 +1577,25 @@ class Sized_relobj : public Relobj
|
|||||||
this->local_got_offsets_.clear();
|
this->local_got_offsets_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Record a mapping from discarded section SHNDX to the corresponding
|
||||||
|
// kept section.
|
||||||
|
void
|
||||||
|
set_kept_comdat_section(unsigned int shndx, Kept_comdat_section* kept)
|
||||||
|
{
|
||||||
|
this->kept_comdat_sections_[shndx] = kept;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the kept section corresponding to the discarded section SHNDX.
|
||||||
|
Kept_comdat_section*
|
||||||
|
get_kept_comdat_section(unsigned int shndx) const
|
||||||
|
{
|
||||||
|
typename Kept_comdat_section_table::const_iterator p =
|
||||||
|
this->kept_comdat_sections_.find(shndx);
|
||||||
|
if (p == this->kept_comdat_sections_.end())
|
||||||
|
return NULL;
|
||||||
|
return p->second;
|
||||||
|
}
|
||||||
|
|
||||||
// The GOT offsets of local symbols. This map also stores GOT offsets
|
// The GOT offsets of local symbols. This map also stores GOT offsets
|
||||||
// for tp-relative offsets for TLS symbols.
|
// for tp-relative offsets for TLS symbols.
|
||||||
typedef Unordered_map<unsigned int, Got_offset_list*> Local_got_offsets;
|
typedef Unordered_map<unsigned int, Got_offset_list*> Local_got_offsets;
|
||||||
@ -1636,6 +1637,14 @@ class Sized_relobj : public Relobj
|
|||||||
// GOT offsets for local non-TLS symbols, and tp-relative offsets
|
// GOT offsets for local non-TLS symbols, and tp-relative offsets
|
||||||
// for TLS symbols, indexed by symbol number.
|
// for TLS symbols, indexed by symbol number.
|
||||||
Local_got_offsets local_got_offsets_;
|
Local_got_offsets local_got_offsets_;
|
||||||
|
// For each input section, the offset of the input section in its
|
||||||
|
// output section. This is -1U if the input section requires a
|
||||||
|
// special mapping.
|
||||||
|
std::vector<Address> section_offsets_;
|
||||||
|
// Table mapping discarded comdat sections to corresponding kept sections.
|
||||||
|
Kept_comdat_section_table kept_comdat_sections_;
|
||||||
|
// Table of kept comdat groups.
|
||||||
|
Comdat_group_table comdat_groups_;
|
||||||
// Whether this object has a GNU style .eh_frame section.
|
// Whether this object has a GNU style .eh_frame section.
|
||||||
bool has_eh_frame_;
|
bool has_eh_frame_;
|
||||||
};
|
};
|
||||||
|
@ -617,7 +617,7 @@ template<bool dynamic, int size, bool big_endian>
|
|||||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
|
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
|
||||||
Symbol* gsym,
|
Symbol* gsym,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
Relobj* relobj,
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
Address address,
|
Address address,
|
||||||
bool is_relative)
|
bool is_relative)
|
||||||
@ -707,7 +707,7 @@ template<bool dynamic, int size, bool big_endian>
|
|||||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
|
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
|
||||||
Output_section* os,
|
Output_section* os,
|
||||||
unsigned int type,
|
unsigned int type,
|
||||||
Relobj* relobj,
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
Address address)
|
Address address)
|
||||||
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
|
: address_(address), local_sym_index_(SECTION_CODE), type_(type),
|
||||||
@ -755,12 +755,7 @@ set_needs_dynsym_index()
|
|||||||
if (!this->is_section_symbol_)
|
if (!this->is_section_symbol_)
|
||||||
this->u1_.relobj->set_needs_output_dynsym_entry(lsi);
|
this->u1_.relobj->set_needs_output_dynsym_entry(lsi);
|
||||||
else
|
else
|
||||||
{
|
this->u1_.relobj->output_section(lsi)->set_needs_dynsym_index();
|
||||||
section_offset_type dummy;
|
|
||||||
Output_section* os = this->u1_.relobj->output_section(lsi, &dummy);
|
|
||||||
gold_assert(os != NULL);
|
|
||||||
os->set_needs_dynsym_index();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -812,8 +807,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
section_offset_type dummy;
|
Output_section* os = this->u1_.relobj->output_section(lsi);
|
||||||
Output_section* os = this->u1_.relobj->output_section(lsi, &dummy);
|
|
||||||
gold_assert(os != NULL);
|
gold_assert(os != NULL);
|
||||||
if (dynamic)
|
if (dynamic)
|
||||||
index = os->dynsym_index();
|
index = os->dynsym_index();
|
||||||
@ -831,7 +825,7 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
|
|||||||
// within the input section.
|
// within the input section.
|
||||||
|
|
||||||
template<bool dynamic, int size, bool big_endian>
|
template<bool dynamic, int size, bool big_endian>
|
||||||
section_offset_type
|
typename elfcpp::Elf_types<size>::Elf_Addr
|
||||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
|
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
|
||||||
local_section_offset(Addend addend) const
|
local_section_offset(Addend addend) const
|
||||||
{
|
{
|
||||||
@ -840,14 +834,14 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
|
|||||||
&& this->local_sym_index_ != INVALID_CODE
|
&& this->local_sym_index_ != INVALID_CODE
|
||||||
&& this->is_section_symbol_);
|
&& this->is_section_symbol_);
|
||||||
const unsigned int lsi = this->local_sym_index_;
|
const unsigned int lsi = this->local_sym_index_;
|
||||||
section_offset_type offset;
|
Output_section* os = this->u1_.relobj->output_section(lsi);
|
||||||
Output_section* os = this->u1_.relobj->output_section(lsi, &offset);
|
|
||||||
gold_assert(os != NULL);
|
gold_assert(os != NULL);
|
||||||
if (offset != -1)
|
Address offset = this->u1_.relobj->get_output_section_offset(lsi);
|
||||||
|
if (offset != -1U)
|
||||||
return offset + addend;
|
return offset + addend;
|
||||||
// This is a merge section.
|
// This is a merge section.
|
||||||
offset = os->output_address(this->u1_.relobj, lsi, addend);
|
offset = os->output_address(this->u1_.relobj, lsi, addend);
|
||||||
gold_assert(offset != -1);
|
gold_assert(offset != -1U);
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,11 +854,10 @@ Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_address() const
|
|||||||
Address address = this->address_;
|
Address address = this->address_;
|
||||||
if (this->shndx_ != INVALID_CODE)
|
if (this->shndx_ != INVALID_CODE)
|
||||||
{
|
{
|
||||||
section_offset_type off;
|
Output_section* os = this->u2_.relobj->output_section(this->shndx_);
|
||||||
Output_section* os = this->u2_.relobj->output_section(this->shndx_,
|
|
||||||
&off);
|
|
||||||
gold_assert(os != NULL);
|
gold_assert(os != NULL);
|
||||||
if (off != -1)
|
Address off = this->u2_.relobj->get_output_section_offset(this->shndx_);
|
||||||
|
if (off != -1U)
|
||||||
address += os->address() + off;
|
address += os->address() + off;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1094,8 +1087,7 @@ Output_data_group<size, big_endian>::do_write(Output_file* of)
|
|||||||
p != this->input_shndxes_.end();
|
p != this->input_shndxes_.end();
|
||||||
++p, ++contents)
|
++p, ++contents)
|
||||||
{
|
{
|
||||||
section_offset_type dummy;
|
Output_section* os = this->relobj_->output_section(*p);
|
||||||
Output_section* os = this->relobj_->output_section(*p, &dummy);
|
|
||||||
|
|
||||||
unsigned int output_shndx;
|
unsigned int output_shndx;
|
||||||
if (os != NULL)
|
if (os != NULL)
|
||||||
@ -1358,8 +1350,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rel(
|
|||||||
this->entries_.push_back(Got_entry());
|
this->entries_.push_back(Got_entry());
|
||||||
unsigned int got_offset = this->last_got_offset();
|
unsigned int got_offset = this->last_got_offset();
|
||||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||||
section_offset_type off;
|
Output_section* os = object->output_section(shndx);
|
||||||
Output_section* os = object->output_section(shndx, &off);
|
|
||||||
rel_dyn->add_output_section(os, r_type_1, this, got_offset);
|
rel_dyn->add_output_section(os, r_type_1, this, got_offset);
|
||||||
|
|
||||||
this->entries_.push_back(Got_entry(object, symndx));
|
this->entries_.push_back(Got_entry(object, symndx));
|
||||||
@ -1389,8 +1380,7 @@ Output_data_got<size, big_endian>::add_local_pair_with_rela(
|
|||||||
this->entries_.push_back(Got_entry());
|
this->entries_.push_back(Got_entry());
|
||||||
unsigned int got_offset = this->last_got_offset();
|
unsigned int got_offset = this->last_got_offset();
|
||||||
object->set_local_got_offset(symndx, got_type, got_offset);
|
object->set_local_got_offset(symndx, got_type, got_offset);
|
||||||
section_offset_type off;
|
Output_section* os = object->output_section(shndx);
|
||||||
Output_section* os = object->output_section(shndx, &off);
|
|
||||||
rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0);
|
rela_dyn->add_output_section(os, r_type_1, this, got_offset, 0);
|
||||||
|
|
||||||
this->entries_.push_back(Got_entry(object, symndx));
|
this->entries_.push_back(Got_entry(object, symndx));
|
||||||
@ -1995,8 +1985,6 @@ Output_section::is_input_address_mapped(const Relobj* object,
|
|||||||
unsigned int shndx,
|
unsigned int shndx,
|
||||||
off_t offset) const
|
off_t offset) const
|
||||||
{
|
{
|
||||||
gold_assert(object->is_section_specially_mapped(shndx));
|
|
||||||
|
|
||||||
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
++p)
|
++p)
|
||||||
@ -2021,7 +2009,6 @@ section_offset_type
|
|||||||
Output_section::output_offset(const Relobj* object, unsigned int shndx,
|
Output_section::output_offset(const Relobj* object, unsigned int shndx,
|
||||||
section_offset_type offset) const
|
section_offset_type offset) const
|
||||||
{
|
{
|
||||||
gold_assert(object->is_section_specially_mapped(shndx));
|
|
||||||
// This can only be called meaningfully when layout is complete.
|
// This can only be called meaningfully when layout is complete.
|
||||||
gold_assert(Output_data::is_layout_complete());
|
gold_assert(Output_data::is_layout_complete());
|
||||||
|
|
||||||
@ -2043,8 +2030,6 @@ uint64_t
|
|||||||
Output_section::output_address(const Relobj* object, unsigned int shndx,
|
Output_section::output_address(const Relobj* object, unsigned int shndx,
|
||||||
off_t offset) const
|
off_t offset) const
|
||||||
{
|
{
|
||||||
gold_assert(object->is_section_specially_mapped(shndx));
|
|
||||||
|
|
||||||
uint64_t addr = this->address() + this->first_input_offset_;
|
uint64_t addr = this->address() + this->first_input_offset_;
|
||||||
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
@ -2076,8 +2061,6 @@ uint64_t
|
|||||||
Output_section::starting_output_address(const Relobj* object,
|
Output_section::starting_output_address(const Relobj* object,
|
||||||
unsigned int shndx) const
|
unsigned int shndx) const
|
||||||
{
|
{
|
||||||
gold_assert(object->is_section_specially_mapped(shndx));
|
|
||||||
|
|
||||||
uint64_t addr = this->address() + this->first_input_offset_;
|
uint64_t addr = this->address() + this->first_input_offset_;
|
||||||
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
for (Input_section_list::const_iterator p = this->input_sections_.begin();
|
||||||
p != this->input_sections_.end();
|
p != this->input_sections_.end();
|
||||||
|
@ -890,7 +890,8 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
|
Output_reloc(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
Address address, bool is_relative);
|
Address address, bool is_relative);
|
||||||
|
|
||||||
Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj,
|
Output_reloc(Symbol* gsym, unsigned int type,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address, bool is_relative);
|
unsigned int shndx, Address address, bool is_relative);
|
||||||
|
|
||||||
// A reloc against a local symbol or local section symbol.
|
// A reloc against a local symbol or local section symbol.
|
||||||
@ -910,7 +911,8 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
|
Output_reloc(Output_section* os, unsigned int type, Output_data* od,
|
||||||
Address address);
|
Address address);
|
||||||
|
|
||||||
Output_reloc(Output_section* os, unsigned int type, Relobj* relobj,
|
Output_reloc(Output_section* os, unsigned int type,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address);
|
unsigned int shndx, Address address);
|
||||||
|
|
||||||
// Return TRUE if this is a RELATIVE relocation.
|
// Return TRUE if this is a RELATIVE relocation.
|
||||||
@ -931,7 +933,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
// For a local section symbol, return the offset of the input
|
// For a local section symbol, return the offset of the input
|
||||||
// section within the output section. ADDEND is the addend being
|
// section within the output section. ADDEND is the addend being
|
||||||
// applied to the input section.
|
// applied to the input section.
|
||||||
section_offset_type
|
Address
|
||||||
local_section_offset(Addend addend) const;
|
local_section_offset(Addend addend) const;
|
||||||
|
|
||||||
// Get the value of the symbol referred to by a Rel relocation when
|
// Get the value of the symbol referred to by a Rel relocation when
|
||||||
@ -1004,7 +1006,7 @@ class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
{
|
{
|
||||||
// If this->shndx_ is not INVALID CODE, the object which holds the
|
// If this->shndx_ is not INVALID CODE, the object which holds the
|
||||||
// input section being used to specify the reloc address.
|
// input section being used to specify the reloc address.
|
||||||
Relobj* relobj;
|
Sized_relobj<size, big_endian>* relobj;
|
||||||
// If this->shndx_ is INVALID_CODE, the output data being used to
|
// If this->shndx_ is INVALID_CODE, the output data being used to
|
||||||
// specify the reloc address. This may be NULL if the reloc
|
// specify the reloc address. This may be NULL if the reloc
|
||||||
// address is absolute.
|
// address is absolute.
|
||||||
@ -1053,7 +1055,8 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
|||||||
: rel_(gsym, type, od, address, is_relative), addend_(addend)
|
: rel_(gsym, type, od, address, is_relative), addend_(addend)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Output_reloc(Symbol* gsym, unsigned int type, Relobj* relobj,
|
Output_reloc(Symbol* gsym, unsigned int type,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address, Addend addend,
|
unsigned int shndx, Address address, Addend addend,
|
||||||
bool is_relative)
|
bool is_relative)
|
||||||
: rel_(gsym, type, relobj, shndx, address, is_relative), addend_(addend)
|
: rel_(gsym, type, relobj, shndx, address, is_relative), addend_(addend)
|
||||||
@ -1086,7 +1089,8 @@ class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
|||||||
: rel_(os, type, od, address), addend_(addend)
|
: rel_(os, type, od, address), addend_(addend)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Output_reloc(Output_section* os, unsigned int type, Relobj* relobj,
|
Output_reloc(Output_section* os, unsigned int type,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address, Addend addend)
|
unsigned int shndx, Address address, Addend addend)
|
||||||
: rel_(os, type, relobj, shndx, address), addend_(addend)
|
: rel_(os, type, relobj, shndx, address), addend_(addend)
|
||||||
{ }
|
{ }
|
||||||
@ -1215,7 +1219,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
{ this->add(od, Output_reloc_type(gsym, type, od, address, false)); }
|
{ this->add(od, Output_reloc_type(gsym, type, od, address, false)); }
|
||||||
|
|
||||||
void
|
void
|
||||||
add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj,
|
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address)
|
unsigned int shndx, Address address)
|
||||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||||
false)); }
|
false)); }
|
||||||
@ -1231,7 +1236,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj,
|
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address, Address addend)
|
unsigned int shndx, Address address, Address addend)
|
||||||
{
|
{
|
||||||
gold_assert(addend == 0);
|
gold_assert(addend == 0);
|
||||||
@ -1248,7 +1254,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
|
|
||||||
void
|
void
|
||||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
Relobj* relobj, unsigned int shndx, Address address)
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
|
unsigned int shndx, Address address)
|
||||||
{
|
{
|
||||||
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||||
true));
|
true));
|
||||||
@ -1327,7 +1334,8 @@ class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
|||||||
|
|
||||||
void
|
void
|
||||||
add_output_section(Output_section* os, unsigned int type, Output_data* od,
|
add_output_section(Output_section* os, unsigned int type, Output_data* od,
|
||||||
Relobj* relobj, unsigned int shndx, Address address)
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
|
unsigned int shndx, Address address)
|
||||||
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
|
{ this->add(od, Output_reloc_type(os, type, relobj, shndx, address)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1359,7 +1367,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
|||||||
false)); }
|
false)); }
|
||||||
|
|
||||||
void
|
void
|
||||||
add_global(Symbol* gsym, unsigned int type, Output_data* od, Relobj* relobj,
|
add_global(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address,
|
unsigned int shndx, Address address,
|
||||||
Addend addend)
|
Addend addend)
|
||||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||||
@ -1377,8 +1386,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
|||||||
|
|
||||||
void
|
void
|
||||||
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
add_global_relative(Symbol* gsym, unsigned int type, Output_data* od,
|
||||||
Relobj* relobj, unsigned int shndx, Address address,
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
Addend addend)
|
unsigned int shndx, Address address, Addend addend)
|
||||||
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
{ this->add(od, Output_reloc_type(gsym, type, relobj, shndx, address,
|
||||||
addend, true)); }
|
addend, true)); }
|
||||||
|
|
||||||
@ -1455,7 +1464,8 @@ class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
|||||||
{ this->add(os, Output_reloc_type(os, type, od, address, addend)); }
|
{ this->add(os, Output_reloc_type(os, type, od, address, addend)); }
|
||||||
|
|
||||||
void
|
void
|
||||||
add_output_section(Output_section* os, unsigned int type, Relobj* relobj,
|
add_output_section(Output_section* os, unsigned int type,
|
||||||
|
Sized_relobj<size, big_endian>* relobj,
|
||||||
unsigned int shndx, Address address, Addend addend)
|
unsigned int shndx, Address address, Addend addend)
|
||||||
{ this->add(os, Output_reloc_type(os, type, relobj, shndx, address,
|
{ this->add(os, Output_reloc_type(os, type, relobj, shndx, address,
|
||||||
addend)); }
|
addend)); }
|
||||||
|
@ -280,7 +280,8 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
|||||||
|
|
||||||
// Copy a relocation against a global symbol.
|
// Copy a relocation against a global symbol.
|
||||||
void
|
void
|
||||||
copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
|
copy_reloc(Symbol_table* symtab, Layout* layout,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx, Output_section* output_section,
|
unsigned int shndx, Output_section* output_section,
|
||||||
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
|
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
|
||||||
{
|
{
|
||||||
|
@ -193,7 +193,8 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
|
|||||||
|
|
||||||
rd->relocs.reserve(shnum / 2);
|
rd->relocs.reserve(shnum / 2);
|
||||||
|
|
||||||
std::vector<Map_to_output>& map_sections(this->map_to_output());
|
const Output_sections& out_sections(this->output_sections());
|
||||||
|
const std::vector<Address>& out_offsets(this->section_offsets_);
|
||||||
|
|
||||||
const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(),
|
const unsigned char *pshdrs = this->get_view(this->elf_file_.shoff(),
|
||||||
shnum * This::shdr_size,
|
shnum * This::shdr_size,
|
||||||
@ -216,7 +217,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output_section* os = map_sections[shndx].output_section;
|
Output_section* os = out_sections[shndx];
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -273,7 +274,7 @@ Sized_relobj<size, big_endian>::do_read_relocs(Read_relocs_data* rd)
|
|||||||
sr.sh_type = sh_type;
|
sr.sh_type = sh_type;
|
||||||
sr.reloc_count = reloc_count;
|
sr.reloc_count = reloc_count;
|
||||||
sr.output_section = os;
|
sr.output_section = os;
|
||||||
sr.needs_special_offset_handling = map_sections[shndx].offset == -1;
|
sr.needs_special_offset_handling = out_offsets[shndx] == -1U;
|
||||||
sr.is_data_section_allocated = is_section_allocated;
|
sr.is_data_section_allocated = is_section_allocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +535,8 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
Views* pviews)
|
Views* pviews)
|
||||||
{
|
{
|
||||||
unsigned int shnum = this->shnum();
|
unsigned int shnum = this->shnum();
|
||||||
const std::vector<Map_to_output>& map_sections(this->map_to_output());
|
const Output_sections& out_sections(this->output_sections());
|
||||||
|
const std::vector<Address>& out_offsets(this->section_offsets_);
|
||||||
|
|
||||||
File_read::Read_multiple rm;
|
File_read::Read_multiple rm;
|
||||||
bool is_sorted = true;
|
bool is_sorted = true;
|
||||||
@ -546,10 +548,10 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
|
|
||||||
pvs->view = NULL;
|
pvs->view = NULL;
|
||||||
|
|
||||||
const Output_section* os = map_sections[i].output_section;
|
const Output_section* os = out_sections[i];
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
continue;
|
continue;
|
||||||
off_t output_offset = map_sections[i].offset;
|
Address output_offset = out_offsets[i];
|
||||||
|
|
||||||
typename This::Shdr shdr(p);
|
typename This::Shdr shdr(p);
|
||||||
|
|
||||||
@ -584,7 +586,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
// In the normal case, this input section is simply mapped to
|
// In the normal case, this input section is simply mapped to
|
||||||
// the output section at offset OUTPUT_OFFSET.
|
// the output section at offset OUTPUT_OFFSET.
|
||||||
|
|
||||||
// However, if OUTPUT_OFFSET == -1, then input data is handled
|
// However, if OUTPUT_OFFSET == -1U, then input data is handled
|
||||||
// specially--e.g., a .eh_frame section. The relocation
|
// specially--e.g., a .eh_frame section. The relocation
|
||||||
// routines need to check for each reloc where it should be
|
// routines need to check for each reloc where it should be
|
||||||
// applied. For this case, we need an input/output view for the
|
// applied. For this case, we need an input/output view for the
|
||||||
@ -602,21 +604,22 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
// final data to the output file.
|
// final data to the output file.
|
||||||
|
|
||||||
off_t output_section_offset;
|
off_t output_section_offset;
|
||||||
off_t output_section_size;
|
Address output_section_size;
|
||||||
if (!os->requires_postprocessing())
|
if (!os->requires_postprocessing())
|
||||||
{
|
{
|
||||||
output_section_offset = os->offset();
|
output_section_offset = os->offset();
|
||||||
output_section_size = os->data_size();
|
output_section_size = convert_types<Address, off_t>(os->data_size());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
output_section_offset = 0;
|
output_section_offset = 0;
|
||||||
output_section_size = os->postprocessing_buffer_size();
|
output_section_size =
|
||||||
|
convert_types<Address, off_t>(os->postprocessing_buffer_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t view_start;
|
off_t view_start;
|
||||||
section_size_type view_size;
|
section_size_type view_size;
|
||||||
if (output_offset != -1)
|
if (output_offset != -1U)
|
||||||
{
|
{
|
||||||
view_start = output_section_offset + output_offset;
|
view_start = output_section_offset + output_offset;
|
||||||
view_size = convert_to_section_size_type(shdr.get_sh_size());
|
view_size = convert_to_section_size_type(shdr.get_sh_size());
|
||||||
@ -630,17 +633,15 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
if (view_size == 0)
|
if (view_size == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
gold_assert(output_offset == -1
|
gold_assert(output_offset == -1U
|
||||||
|| (output_offset >= 0
|
|| output_offset + view_size <= output_section_size);
|
||||||
&& (output_offset + static_cast<off_t>(view_size)
|
|
||||||
<= output_section_size)));
|
|
||||||
|
|
||||||
unsigned char* view;
|
unsigned char* view;
|
||||||
if (os->requires_postprocessing())
|
if (os->requires_postprocessing())
|
||||||
{
|
{
|
||||||
unsigned char* buffer = os->postprocessing_buffer();
|
unsigned char* buffer = os->postprocessing_buffer();
|
||||||
view = buffer + view_start;
|
view = buffer + view_start;
|
||||||
if (output_offset != -1)
|
if (output_offset != -1U)
|
||||||
{
|
{
|
||||||
off_t sh_offset = shdr.get_sh_offset();
|
off_t sh_offset = shdr.get_sh_offset();
|
||||||
if (!rm.empty() && rm.back().file_offset > sh_offset)
|
if (!rm.empty() && rm.back().file_offset > sh_offset)
|
||||||
@ -651,7 +652,7 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (output_offset == -1)
|
if (output_offset == -1U)
|
||||||
view = of->get_input_output_view(view_start, view_size);
|
view = of->get_input_output_view(view_start, view_size);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -666,11 +667,11 @@ Sized_relobj<size, big_endian>::write_sections(const unsigned char* pshdrs,
|
|||||||
|
|
||||||
pvs->view = view;
|
pvs->view = view;
|
||||||
pvs->address = os->address();
|
pvs->address = os->address();
|
||||||
if (output_offset != -1)
|
if (output_offset != -1U)
|
||||||
pvs->address += output_offset;
|
pvs->address += output_offset;
|
||||||
pvs->offset = view_start;
|
pvs->offset = view_start;
|
||||||
pvs->view_size = view_size;
|
pvs->view_size = view_size;
|
||||||
pvs->is_input_output_view = output_offset == -1;
|
pvs->is_input_output_view = output_offset == -1U;
|
||||||
pvs->is_postprocessing_view = os->requires_postprocessing();
|
pvs->is_postprocessing_view = os->requires_postprocessing();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +699,8 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
|||||||
unsigned int shnum = this->shnum();
|
unsigned int shnum = this->shnum();
|
||||||
Sized_target<size, big_endian>* target = this->sized_target();
|
Sized_target<size, big_endian>* target = this->sized_target();
|
||||||
|
|
||||||
const std::vector<Map_to_output>& map_sections(this->map_to_output());
|
const Output_sections& out_sections(this->output_sections());
|
||||||
|
const std::vector<Address>& out_offsets(this->section_offsets_);
|
||||||
|
|
||||||
Relocate_info<size, big_endian> relinfo;
|
Relocate_info<size, big_endian> relinfo;
|
||||||
relinfo.options = &options;
|
relinfo.options = &options;
|
||||||
@ -723,14 +725,14 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Output_section* os = map_sections[index].output_section;
|
Output_section* os = out_sections[index];
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
{
|
{
|
||||||
// This relocation section is against a section which we
|
// This relocation section is against a section which we
|
||||||
// discarded.
|
// discarded.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
off_t output_offset = map_sections[index].offset;
|
Address output_offset = out_offsets[index];
|
||||||
|
|
||||||
gold_assert((*pviews)[index].view != NULL);
|
gold_assert((*pviews)[index].view != NULL);
|
||||||
if (parameters->options().relocatable())
|
if (parameters->options().relocatable())
|
||||||
@ -770,7 +772,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gold_assert(output_offset != -1
|
gold_assert(output_offset != -1U
|
||||||
|| this->relocs_must_follow_section_writes());
|
|| this->relocs_must_follow_section_writes());
|
||||||
|
|
||||||
relinfo.reloc_shndx = i;
|
relinfo.reloc_shndx = i;
|
||||||
@ -782,7 +784,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
|||||||
prelocs,
|
prelocs,
|
||||||
reloc_count,
|
reloc_count,
|
||||||
os,
|
os,
|
||||||
output_offset == -1,
|
output_offset == -1U,
|
||||||
(*pviews)[index].view,
|
(*pviews)[index].view,
|
||||||
(*pviews)[index].address,
|
(*pviews)[index].address,
|
||||||
(*pviews)[index].view_size);
|
(*pviews)[index].view_size);
|
||||||
@ -825,7 +827,7 @@ Sized_relobj<size, big_endian>::emit_relocs(
|
|||||||
const unsigned char* prelocs,
|
const unsigned char* prelocs,
|
||||||
size_t reloc_count,
|
size_t reloc_count,
|
||||||
Output_section* output_section,
|
Output_section* output_section,
|
||||||
off_t offset_in_output_section,
|
typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
|
||||||
unsigned char* view,
|
unsigned char* view,
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr address,
|
typename elfcpp::Elf_types<size>::Elf_Addr address,
|
||||||
section_size_type view_size,
|
section_size_type view_size,
|
||||||
@ -861,7 +863,7 @@ Sized_relobj<size, big_endian>::emit_relocs_reltype(
|
|||||||
const unsigned char* prelocs,
|
const unsigned char* prelocs,
|
||||||
size_t reloc_count,
|
size_t reloc_count,
|
||||||
Output_section* output_section,
|
Output_section* output_section,
|
||||||
off_t offset_in_output_section,
|
typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
|
||||||
unsigned char* view,
|
unsigned char* view,
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr address,
|
typename elfcpp::Elf_types<size>::Elf_Addr address,
|
||||||
section_size_type view_size,
|
section_size_type view_size,
|
||||||
|
@ -296,7 +296,8 @@ class Target_sparc : public Sized_target<size, big_endian>
|
|||||||
|
|
||||||
// Copy a relocation against a global symbol.
|
// Copy a relocation against a global symbol.
|
||||||
void
|
void
|
||||||
copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
|
copy_reloc(Symbol_table* symtab, Layout* layout,
|
||||||
|
Sized_relobj<size, big_endian>* object,
|
||||||
unsigned int shndx, Output_section* output_section,
|
unsigned int shndx, Output_section* output_section,
|
||||||
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
|
Symbol* sym, const elfcpp::Rela<size, big_endian>& reloc)
|
||||||
{
|
{
|
||||||
|
@ -357,8 +357,7 @@ Symbol::output_section() const
|
|||||||
{
|
{
|
||||||
gold_assert(!this->u_.from_object.object->is_dynamic());
|
gold_assert(!this->u_.from_object.object->is_dynamic());
|
||||||
Relobj* relobj = static_cast<Relobj*>(this->u_.from_object.object);
|
Relobj* relobj = static_cast<Relobj*>(this->u_.from_object.object);
|
||||||
section_offset_type dummy;
|
return relobj->output_section(shndx);
|
||||||
return relobj->output_section(shndx, &dummy);
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1943,6 +1942,8 @@ template<int size>
|
|||||||
bool
|
bool
|
||||||
Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
|
Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
|
||||||
{
|
{
|
||||||
|
typedef typename Sized_symbol<size>::Value_type Value_type;
|
||||||
|
|
||||||
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(unsized_sym);
|
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(unsized_sym);
|
||||||
|
|
||||||
// The default version of a symbol may appear twice in the symbol
|
// The default version of a symbol may appear twice in the symbol
|
||||||
@ -1958,7 +1959,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
typename Sized_symbol<size>::Value_type value;
|
Value_type value;
|
||||||
|
|
||||||
switch (sym->source())
|
switch (sym->source())
|
||||||
{
|
{
|
||||||
@ -1991,8 +1992,7 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Relobj* relobj = static_cast<Relobj*>(symobj);
|
Relobj* relobj = static_cast<Relobj*>(symobj);
|
||||||
section_offset_type secoff;
|
Output_section* os = relobj->output_section(shndx);
|
||||||
Output_section* os = relobj->output_section(shndx, &secoff);
|
|
||||||
|
|
||||||
if (os == NULL)
|
if (os == NULL)
|
||||||
{
|
{
|
||||||
@ -2001,6 +2001,8 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t secoff64 = relobj->output_section_offset(shndx);
|
||||||
|
Value_type secoff = convert_types<Value_type, uint64_t>(secoff64);
|
||||||
if (sym->type() == elfcpp::STT_TLS)
|
if (sym->type() == elfcpp::STT_TLS)
|
||||||
value = sym->value() + os->tls_offset() + secoff;
|
value = sym->value() + os->tls_offset() + secoff;
|
||||||
else
|
else
|
||||||
@ -2208,9 +2210,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Relobj* relobj = static_cast<Relobj*>(symobj);
|
Relobj* relobj = static_cast<Relobj*>(symobj);
|
||||||
section_offset_type secoff;
|
Output_section* os = relobj->output_section(in_shndx);
|
||||||
Output_section* os = relobj->output_section(in_shndx,
|
|
||||||
&secoff);
|
|
||||||
gold_assert(os != NULL);
|
gold_assert(os != NULL);
|
||||||
shndx = os->out_shndx();
|
shndx = os->out_shndx();
|
||||||
|
|
||||||
|
@ -417,12 +417,7 @@ scan_relocatable_relocs(
|
|||||||
{
|
{
|
||||||
strategy = scan.local_section_strategy(r_type, object);
|
strategy = scan.local_section_strategy(r_type, object);
|
||||||
if (strategy != Relocatable_relocs::RELOC_DISCARD)
|
if (strategy != Relocatable_relocs::RELOC_DISCARD)
|
||||||
{
|
object->output_section(shndx)->set_needs_symtab_index();
|
||||||
section_offset_type dummy;
|
|
||||||
Output_section* os = object->output_section(shndx,
|
|
||||||
&dummy);
|
|
||||||
os->set_needs_symtab_index();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -441,7 +436,7 @@ relocate_for_relocatable(
|
|||||||
const unsigned char* prelocs,
|
const unsigned char* prelocs,
|
||||||
size_t reloc_count,
|
size_t reloc_count,
|
||||||
Output_section* output_section,
|
Output_section* output_section,
|
||||||
off_t offset_in_output_section,
|
typename elfcpp::Elf_types<size>::Elf_Addr offset_in_output_section,
|
||||||
const Relocatable_relocs* rr,
|
const Relocatable_relocs* rr,
|
||||||
unsigned char* view,
|
unsigned char* view,
|
||||||
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
|
typename elfcpp::Elf_types<size>::Elf_Addr view_address,
|
||||||
@ -449,6 +444,7 @@ relocate_for_relocatable(
|
|||||||
unsigned char* reloc_view,
|
unsigned char* reloc_view,
|
||||||
section_size_type reloc_view_size)
|
section_size_type reloc_view_size)
|
||||||
{
|
{
|
||||||
|
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||||
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
|
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
|
||||||
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write
|
typedef typename Reloc_types<sh_type, size, big_endian>::Reloc_write
|
||||||
Reltype_write;
|
Reltype_write;
|
||||||
@ -500,8 +496,7 @@ relocate_for_relocatable(
|
|||||||
unsigned int shndx =
|
unsigned int shndx =
|
||||||
object->local_symbol_input_shndx(r_sym, &is_ordinary);
|
object->local_symbol_input_shndx(r_sym, &is_ordinary);
|
||||||
gold_assert(is_ordinary);
|
gold_assert(is_ordinary);
|
||||||
section_offset_type dummy;
|
Output_section* os = object->output_section(shndx);
|
||||||
Output_section* os = object->output_section(shndx, &dummy);
|
|
||||||
gold_assert(os != NULL);
|
gold_assert(os != NULL);
|
||||||
gold_assert(os->needs_symtab_index());
|
gold_assert(os->needs_symtab_index());
|
||||||
new_symndx = os->symtab_index();
|
new_symndx = os->symtab_index();
|
||||||
@ -526,16 +521,19 @@ relocate_for_relocatable(
|
|||||||
// Get the new offset--the location in the output section where
|
// Get the new offset--the location in the output section where
|
||||||
// this relocation should be applied.
|
// this relocation should be applied.
|
||||||
|
|
||||||
off_t offset = reloc.get_r_offset();
|
Address offset = reloc.get_r_offset();
|
||||||
off_t new_offset;
|
Address new_offset;
|
||||||
if (offset_in_output_section != -1)
|
if (offset_in_output_section != -1U)
|
||||||
new_offset = offset + offset_in_output_section;
|
new_offset = offset + offset_in_output_section;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
new_offset = output_section->output_offset(object,
|
section_offset_type sot_offset =
|
||||||
relinfo->data_shndx,
|
convert_types<section_offset_type, Address>(offset);
|
||||||
offset);
|
section_offset_type new_sot_offset =
|
||||||
gold_assert(new_offset != -1);
|
output_section->output_offset(object, relinfo->data_shndx,
|
||||||
|
sot_offset);
|
||||||
|
gold_assert(new_sot_offset != -1);
|
||||||
|
new_offset = new_sot_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In an object file, r_offset is an offset within the section.
|
// In an object file, r_offset is an offset within the section.
|
||||||
@ -544,7 +542,7 @@ relocate_for_relocatable(
|
|||||||
if (!parameters->options().relocatable())
|
if (!parameters->options().relocatable())
|
||||||
{
|
{
|
||||||
new_offset += view_address;
|
new_offset += view_address;
|
||||||
if (offset_in_output_section != -1)
|
if (offset_in_output_section != -1U)
|
||||||
new_offset -= offset_in_output_section;
|
new_offset -= offset_in_output_section;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +368,8 @@ class Target_x86_64 : public Sized_target<64, false>
|
|||||||
|
|
||||||
// Add a potential copy relocation.
|
// Add a potential copy relocation.
|
||||||
void
|
void
|
||||||
copy_reloc(Symbol_table* symtab, Layout* layout, Relobj* object,
|
copy_reloc(Symbol_table* symtab, Layout* layout,
|
||||||
|
Sized_relobj<64, false>* object,
|
||||||
unsigned int shndx, Output_section* output_section,
|
unsigned int shndx, Output_section* output_section,
|
||||||
Symbol* sym, const elfcpp::Rela<64, false>& reloc)
|
Symbol* sym, const elfcpp::Rela<64, false>& reloc)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user