* target.h (Target::plt_fde_location, do_plt_fde_location): Declare.
* target.cc (Target::do_plt_fde_location): New function. * ehframe.h (class FDE): Add post_map field to u_.from_linker, accessor function, and constructor param. (struct Post_fde, Post_fdes): Declare. (Cie::write): Add post_fdes param. * ehframe.cc (Fde::write): Use plt_fde_location. (struct Post_fde): Define. (Cie::write): Stash FDEs added post merge mapping. (Eh_frame::add_ehframe_for_plt): Assert no new CIEs after mapping. Adjust Fde constructor call. Bump final_data_size_ for post map FDEs. (Eh_frame::do_sized_write): Arrange to write post map FDES after other FDEs. * powerpc.cc (Target_powerpc::do_plt_fde_location): New function. (Target_powerpc::has_glink): New function. (Target_powerpc::do_relax): Add eh_frame info for stubs. (struct Eh_cie, eh_frame_cie, glink_eh_frame_fde_64, glink_eh_frame_fde_32, default_fde): New data. (Stub_table::eh_frame_added_): New var. (Stub_table::find_long_branch_entry, stub_address, stub_offset): Make const. (Stub_table::add_eh_frame): New function. (Output_data_glink::add_eh_frame): New function. (Target_powerpc::make_glink_section): Call add_eh_frame.
This commit is contained in:
parent
71091f23fd
commit
9d5781f8a2
@ -1,3 +1,30 @@
|
||||
2013-02-28 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* target.h (Target::plt_fde_location, do_plt_fde_location): Declare.
|
||||
* target.cc (Target::do_plt_fde_location): New function.
|
||||
* ehframe.h (class FDE): Add post_map field to u_.from_linker,
|
||||
accessor function, and constructor param.
|
||||
(struct Post_fde, Post_fdes): Declare.
|
||||
(Cie::write): Add post_fdes param.
|
||||
* ehframe.cc (Fde::write): Use plt_fde_location.
|
||||
(struct Post_fde): Define.
|
||||
(Cie::write): Stash FDEs added post merge mapping.
|
||||
(Eh_frame::add_ehframe_for_plt): Assert no new CIEs after mapping.
|
||||
Adjust Fde constructor call. Bump final_data_size_ for post map FDEs.
|
||||
(Eh_frame::do_sized_write): Arrange to write post map FDES after
|
||||
other FDEs.
|
||||
* powerpc.cc (Target_powerpc::do_plt_fde_location): New function.
|
||||
(Target_powerpc::has_glink): New function.
|
||||
(Target_powerpc::do_relax): Add eh_frame info for stubs.
|
||||
(struct Eh_cie, eh_frame_cie, glink_eh_frame_fde_64,
|
||||
glink_eh_frame_fde_32, default_fde): New data.
|
||||
(Stub_table::eh_frame_added_): New var.
|
||||
(Stub_table::find_long_branch_entry, stub_address, stub_offset):
|
||||
Make const.
|
||||
(Stub_table::add_eh_frame): New function.
|
||||
(Output_data_glink::add_eh_frame): New function.
|
||||
(Target_powerpc::make_glink_section): Call add_eh_frame.
|
||||
|
||||
2013-02-15 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* options.h (DEFINE_uint64_alias): Define.
|
||||
|
@ -368,10 +368,13 @@ Fde::write(unsigned char* oview, section_offset_type offset,
|
||||
if (this->object_ == NULL)
|
||||
{
|
||||
gold_assert(memcmp(oview + offset + 8, "\0\0\0\0\0\0\0\0", 8) == 0);
|
||||
Output_data* plt = this->u_.from_linker.plt;
|
||||
uint64_t poffset = plt->address() - (address + offset + 8);
|
||||
uint64_t paddress;
|
||||
off_t psize;
|
||||
parameters->target().plt_fde_location(this->u_.from_linker.plt,
|
||||
oview + offset + 8,
|
||||
&paddress, &psize);
|
||||
uint64_t poffset = paddress - (address + offset + 8);
|
||||
int32_t spoffset = static_cast<int32_t>(poffset);
|
||||
off_t psize = plt->data_size();
|
||||
uint32_t upsize = static_cast<uint32_t>(psize);
|
||||
if (static_cast<uint64_t>(static_cast<int64_t>(spoffset)) != poffset
|
||||
|| static_cast<off_t>(upsize) != psize)
|
||||
@ -438,15 +441,30 @@ Cie::set_output_offset(section_offset_type output_offset,
|
||||
return output_offset + length;
|
||||
}
|
||||
|
||||
// Write the CIE to OVIEW starting at OFFSET. EH_FRAME_HDR is for FDE
|
||||
// recording. Round up the bytes to ADDRALIGN. Return the new
|
||||
// offset.
|
||||
// A FDE plus some info from a CIE to allow later writing of the FDE.
|
||||
|
||||
struct Post_fde
|
||||
{
|
||||
Post_fde(Fde* f, section_offset_type cie_off, unsigned char encoding)
|
||||
: fde(f), cie_offset(cie_off), fde_encoding(encoding)
|
||||
{ }
|
||||
|
||||
Fde* fde;
|
||||
section_offset_type cie_offset;
|
||||
unsigned char fde_encoding;
|
||||
};
|
||||
|
||||
// Write the CIE to OVIEW starting at OFFSET. Round up the bytes to
|
||||
// ADDRALIGN. ADDRESS is the virtual address of OVIEW.
|
||||
// EH_FRAME_HDR is the exception frame header for FDE recording.
|
||||
// POST_FDES stashes FDEs created after mappings were done, for later
|
||||
// writing. Return the new offset.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
section_offset_type
|
||||
Cie::write(unsigned char* oview, section_offset_type offset,
|
||||
uint64_t address, unsigned int addralign,
|
||||
Eh_frame_hdr* eh_frame_hdr)
|
||||
Eh_frame_hdr* eh_frame_hdr, Post_fdes* post_fdes)
|
||||
{
|
||||
gold_assert((offset & (addralign - 1)) == 0);
|
||||
|
||||
@ -479,9 +497,14 @@ Cie::write(unsigned char* oview, section_offset_type offset,
|
||||
for (std::vector<Fde*>::const_iterator p = this->fdes_.begin();
|
||||
p != this->fdes_.end();
|
||||
++p)
|
||||
offset = (*p)->write<size, big_endian>(oview, offset, address, addralign,
|
||||
cie_offset, fde_encoding,
|
||||
eh_frame_hdr);
|
||||
{
|
||||
if ((*p)->post_map())
|
||||
post_fdes->push_back(new Post_fde(*p, cie_offset, fde_encoding));
|
||||
else
|
||||
offset = (*p)->write<size, big_endian>(oview, offset, address,
|
||||
addralign, cie_offset,
|
||||
fde_encoding, eh_frame_hdr);
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
@ -1039,12 +1062,16 @@ Eh_frame::add_ehframe_for_plt(Output_data* plt, const unsigned char* cie_data,
|
||||
pcie = *find_cie;
|
||||
else
|
||||
{
|
||||
gold_assert(!this->mappings_are_done_);
|
||||
pcie = new Cie(cie);
|
||||
this->cie_offsets_.insert(pcie);
|
||||
}
|
||||
|
||||
Fde* fde = new Fde(plt, fde_data, fde_length);
|
||||
Fde* fde = new Fde(plt, fde_data, fde_length, this->mappings_are_done_);
|
||||
pcie->add_fde(fde);
|
||||
|
||||
if (this->mappings_are_done_)
|
||||
this->final_data_size_ += align_address(fde_length + 8, this->addralign());
|
||||
}
|
||||
|
||||
// Return the number of FDEs.
|
||||
@ -1169,17 +1196,28 @@ Eh_frame::do_sized_write(unsigned char* oview)
|
||||
uint64_t address = this->address();
|
||||
unsigned int addralign = this->addralign();
|
||||
section_offset_type o = 0;
|
||||
Post_fdes post_fdes;
|
||||
for (Unmergeable_cie_offsets::iterator p =
|
||||
this->unmergeable_cie_offsets_.begin();
|
||||
p != this->unmergeable_cie_offsets_.end();
|
||||
++p)
|
||||
o = (*p)->write<size, big_endian>(oview, o, address, addralign,
|
||||
this->eh_frame_hdr_);
|
||||
this->eh_frame_hdr_, &post_fdes);
|
||||
for (Cie_offsets::iterator p = this->cie_offsets_.begin();
|
||||
p != this->cie_offsets_.end();
|
||||
++p)
|
||||
o = (*p)->write<size, big_endian>(oview, o, address, addralign,
|
||||
this->eh_frame_hdr_);
|
||||
this->eh_frame_hdr_, &post_fdes);
|
||||
for (Post_fdes::iterator p = post_fdes.begin();
|
||||
p != post_fdes.end();
|
||||
++p)
|
||||
{
|
||||
o = (*p)->fde->write<size, big_endian>(oview, o, address, addralign,
|
||||
(*p)->cie_offset,
|
||||
(*p)->fde_encoding,
|
||||
this->eh_frame_hdr_);
|
||||
delete *p;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_TARGET_32_LITTLE
|
||||
|
@ -174,10 +174,14 @@ class Fde
|
||||
}
|
||||
|
||||
// Create an FDE associated with a PLT.
|
||||
Fde(Output_data* plt, const unsigned char* contents, size_t length)
|
||||
Fde(Output_data* plt, const unsigned char* contents, size_t length,
|
||||
bool post_map)
|
||||
: object_(NULL),
|
||||
contents_(reinterpret_cast<const char*>(contents), length)
|
||||
{ this->u_.from_linker.plt = plt; }
|
||||
{
|
||||
this->u_.from_linker.plt = plt;
|
||||
this->u_.from_linker.post_map = post_map;
|
||||
}
|
||||
|
||||
// Return the length of this FDE. Add 4 for the length and 4 for
|
||||
// the offset to the CIE.
|
||||
@ -196,6 +200,11 @@ class Fde
|
||||
output_offset);
|
||||
}
|
||||
|
||||
// Return whether this FDE was added after merge mapping.
|
||||
bool
|
||||
post_map()
|
||||
{ return this->object_ == NULL && this->u_.from_linker.post_map; }
|
||||
|
||||
// Write the FDE to OVIEW starting at OFFSET. FDE_ENCODING is the
|
||||
// encoding, from the CIE. Round up the bytes to ADDRALIGN if
|
||||
// necessary. ADDRESS is the virtual address of OVIEW. Record the
|
||||
@ -229,12 +238,19 @@ class Fde
|
||||
// The only linker generated FDEs are for PLT sections, and this
|
||||
// points to the PLT section.
|
||||
Output_data* plt;
|
||||
// Set if the FDE was added after merge mapping.
|
||||
bool post_map;
|
||||
} from_linker;
|
||||
} u_;
|
||||
// FDE data.
|
||||
std::string contents_;
|
||||
};
|
||||
|
||||
// FDEs stashed for later processing.
|
||||
|
||||
struct Post_fde;
|
||||
typedef std::vector<Post_fde*> Post_fdes;
|
||||
|
||||
// This class holds a CIE.
|
||||
|
||||
class Cie
|
||||
@ -284,14 +300,16 @@ class Cie
|
||||
set_output_offset(section_offset_type output_offset, unsigned int addralign,
|
||||
Merge_map*);
|
||||
|
||||
// Write the CIE to OVIEW starting at OFFSET. EH_FRAME_HDR is the
|
||||
// exception frame header for FDE recording. Round up the bytes to
|
||||
// ADDRALIGN. ADDRESS is the virtual address of OVIEW. Return the
|
||||
// new offset.
|
||||
// Write the CIE to OVIEW starting at OFFSET. Round up the bytes to
|
||||
// ADDRALIGN. ADDRESS is the virtual address of OVIEW.
|
||||
// EH_FRAME_HDR is the exception frame header for FDE recording.
|
||||
// POST_FDES stashes FDEs created after mappings were done, for later
|
||||
// writing. Return the new offset.
|
||||
template<int size, bool big_endian>
|
||||
section_offset_type
|
||||
write(unsigned char* oview, section_offset_type offset, uint64_t address,
|
||||
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr);
|
||||
unsigned int addralign, Eh_frame_hdr* eh_frame_hdr,
|
||||
Post_fdes* post_fdes);
|
||||
|
||||
friend bool operator<(const Cie&, const Cie&);
|
||||
friend bool operator==(const Cie&, const Cie&);
|
||||
|
185
gold/powerpc.cc
185
gold/powerpc.cc
@ -25,6 +25,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include "elfcpp.h"
|
||||
#include "dwarf.h"
|
||||
#include "parameters.h"
|
||||
#include "reloc.h"
|
||||
#include "powerpc.h"
|
||||
@ -394,6 +395,10 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
bool
|
||||
do_relax(int, const Input_objects*, Symbol_table*, Layout*, const Task*);
|
||||
|
||||
void
|
||||
do_plt_fde_location(const Output_data*, unsigned char*,
|
||||
uint64_t*, off_t*) const;
|
||||
|
||||
// Stash info about branches, for stub generation.
|
||||
void
|
||||
push_branch(Powerpc_relobj<size, big_endian>* ppc_object,
|
||||
@ -526,6 +531,9 @@ class Target_powerpc : public Sized_target<size, big_endian>
|
||||
return this->glink_;
|
||||
}
|
||||
|
||||
bool has_glink() const
|
||||
{ return this->glink_ != NULL; }
|
||||
|
||||
// Get the GOT section.
|
||||
const Output_data_got_powerpc<size, big_endian>*
|
||||
got_section() const
|
||||
@ -2277,6 +2285,7 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
|
||||
if ((*p)->size_update())
|
||||
{
|
||||
again = true;
|
||||
(*p)->add_eh_frame(layout);
|
||||
os_need_update.insert((*p)->output_section());
|
||||
}
|
||||
}
|
||||
@ -2332,6 +2341,54 @@ Target_powerpc<size, big_endian>::do_relax(int pass,
|
||||
return again;
|
||||
}
|
||||
|
||||
template<int size, bool big_endian>
|
||||
void
|
||||
Target_powerpc<size, big_endian>::do_plt_fde_location(const Output_data* plt,
|
||||
unsigned char* oview,
|
||||
uint64_t* paddress,
|
||||
off_t* plen) const
|
||||
{
|
||||
uint64_t address = plt->address();
|
||||
off_t len = plt->data_size();
|
||||
|
||||
if (plt == this->glink_)
|
||||
{
|
||||
// See Output_data_glink::do_write() for glink contents.
|
||||
if (size == 64)
|
||||
{
|
||||
// There is one word before __glink_PLTresolve
|
||||
address += 8;
|
||||
len -= 8;
|
||||
}
|
||||
else if (parameters->options().output_is_position_independent())
|
||||
{
|
||||
// There are two FDEs for a position independent glink.
|
||||
// The first covers the branch table, the second
|
||||
// __glink_PLTresolve at the end of glink.
|
||||
off_t resolve_size = this->glink_->pltresolve_size;
|
||||
if (oview[9] == 0)
|
||||
len -= resolve_size;
|
||||
else
|
||||
{
|
||||
address += len - resolve_size;
|
||||
len = resolve_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Must be a stub table.
|
||||
const Stub_table<size, big_endian>* stub_table
|
||||
= static_cast<const Stub_table<size, big_endian>*>(plt);
|
||||
uint64_t stub_address = stub_table->stub_address();
|
||||
len -= stub_address - address;
|
||||
address = stub_address;
|
||||
}
|
||||
|
||||
*paddress = address;
|
||||
*plen = len;
|
||||
}
|
||||
|
||||
// A class to handle the PLT data.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
@ -2774,6 +2831,60 @@ ha(uint32_t a)
|
||||
return hi(a + 0x8000);
|
||||
}
|
||||
|
||||
template<int size>
|
||||
struct Eh_cie
|
||||
{
|
||||
static const unsigned char eh_frame_cie[12];
|
||||
};
|
||||
|
||||
template<int size>
|
||||
const unsigned char Eh_cie<size>::eh_frame_cie[] =
|
||||
{
|
||||
1, // CIE version.
|
||||
'z', 'R', 0, // Augmentation string.
|
||||
4, // Code alignment.
|
||||
0x80 - size / 8 , // Data alignment.
|
||||
65, // RA reg.
|
||||
1, // Augmentation size.
|
||||
(elfcpp::DW_EH_PE_pcrel
|
||||
| elfcpp::DW_EH_PE_sdata4), // FDE encoding.
|
||||
elfcpp::DW_CFA_def_cfa, 1, 0 // def_cfa: r1 offset 0.
|
||||
};
|
||||
|
||||
// Describe __glink_PLTresolve use of LR, 64-bit version.
|
||||
static const unsigned char glink_eh_frame_fde_64[] =
|
||||
{
|
||||
0, 0, 0, 0, // Replaced with offset to .glink.
|
||||
0, 0, 0, 0, // Replaced with size of .glink.
|
||||
0, // Augmentation size.
|
||||
elfcpp::DW_CFA_advance_loc + 1,
|
||||
elfcpp::DW_CFA_register, 65, 12,
|
||||
elfcpp::DW_CFA_advance_loc + 4,
|
||||
elfcpp::DW_CFA_restore_extended, 65
|
||||
};
|
||||
|
||||
// Describe __glink_PLTresolve use of LR, 32-bit version.
|
||||
static const unsigned char glink_eh_frame_fde_32[] =
|
||||
{
|
||||
0, 0, 0, 0, // Replaced with offset to .glink.
|
||||
0, 0, 0, 0, // Replaced with size of .glink.
|
||||
0, // Augmentation size.
|
||||
elfcpp::DW_CFA_advance_loc + 2,
|
||||
elfcpp::DW_CFA_register, 65, 0,
|
||||
elfcpp::DW_CFA_advance_loc + 4,
|
||||
elfcpp::DW_CFA_restore_extended, 65
|
||||
};
|
||||
|
||||
static const unsigned char default_fde[] =
|
||||
{
|
||||
0, 0, 0, 0, // Replaced with offset to stubs.
|
||||
0, 0, 0, 0, // Replaced with size of stubs.
|
||||
0, // Augmentation size.
|
||||
elfcpp::DW_CFA_nop, // Pad.
|
||||
elfcpp::DW_CFA_nop,
|
||||
elfcpp::DW_CFA_nop
|
||||
};
|
||||
|
||||
template<bool big_endian>
|
||||
static inline void
|
||||
write_insn(unsigned char* p, uint32_t v)
|
||||
@ -2797,7 +2908,7 @@ class Stub_table : public Output_relaxed_input_section
|
||||
: Output_relaxed_input_section(NULL, 0, 0),
|
||||
targ_(targ), plt_call_stubs_(), long_branch_stubs_(),
|
||||
orig_data_size_(0), plt_size_(0), last_plt_size_(0),
|
||||
branch_size_(0), last_branch_size_(0)
|
||||
branch_size_(0), last_branch_size_(0), eh_frame_added_(false)
|
||||
{ }
|
||||
|
||||
// Delayed Output_relaxed_input_section init.
|
||||
@ -2842,7 +2953,8 @@ class Stub_table : public Output_relaxed_input_section
|
||||
add_long_branch_entry(const Powerpc_relobj<size, big_endian>*, Address);
|
||||
|
||||
Address
|
||||
find_long_branch_entry(const Powerpc_relobj<size, big_endian>*, Address);
|
||||
find_long_branch_entry(const Powerpc_relobj<size, big_endian>*,
|
||||
Address) const;
|
||||
|
||||
void
|
||||
clear_stubs()
|
||||
@ -2871,14 +2983,14 @@ class Stub_table : public Output_relaxed_input_section
|
||||
}
|
||||
|
||||
Address
|
||||
stub_address()
|
||||
stub_address() const
|
||||
{
|
||||
return align_address(this->address() + this->orig_data_size_,
|
||||
this->stub_align());
|
||||
}
|
||||
|
||||
Address
|
||||
stub_offset()
|
||||
stub_offset() const
|
||||
{
|
||||
return align_address(this->offset() + this->orig_data_size_,
|
||||
this->stub_align());
|
||||
@ -2919,6 +3031,35 @@ class Stub_table : public Output_relaxed_input_section
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add .eh_frame info for this stub section. Unlike other linker
|
||||
// generated .eh_frame this is added late in the link, because we
|
||||
// only want the .eh_frame info if this particular stub section is
|
||||
// non-empty.
|
||||
void
|
||||
add_eh_frame(Layout* layout)
|
||||
{
|
||||
if (!this->eh_frame_added_)
|
||||
{
|
||||
if (!parameters->options().ld_generated_unwind_info())
|
||||
return;
|
||||
|
||||
// Since we add stub .eh_frame info late, it must be placed
|
||||
// after all other linker generated .eh_frame info so that
|
||||
// merge mapping need not be updated for input sections.
|
||||
// There is no provision to use a different CIE to that used
|
||||
// by .glink.
|
||||
if (!this->targ_->has_glink())
|
||||
return;
|
||||
|
||||
layout->add_eh_frame_for_plt(this,
|
||||
Eh_cie<size>::eh_frame_cie,
|
||||
sizeof (Eh_cie<size>::eh_frame_cie),
|
||||
default_fde,
|
||||
sizeof (default_fde));
|
||||
this->eh_frame_added_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
Target_powerpc<size, big_endian>*
|
||||
targ() const
|
||||
{ return targ_; }
|
||||
@ -3118,6 +3259,8 @@ class Stub_table : public Output_relaxed_input_section
|
||||
section_size_type orig_data_size_;
|
||||
// size of stubs
|
||||
section_size_type plt_size_, last_plt_size_, branch_size_, last_branch_size_;
|
||||
// Whether .eh_frame info has been created for this stub section.
|
||||
bool eh_frame_added_;
|
||||
};
|
||||
|
||||
// Make a new stub table, and record.
|
||||
@ -3261,7 +3404,7 @@ template<int size, bool big_endian>
|
||||
typename Stub_table<size, big_endian>::Address
|
||||
Stub_table<size, big_endian>::find_long_branch_entry(
|
||||
const Powerpc_relobj<size, big_endian>* object,
|
||||
Address to)
|
||||
Address to) const
|
||||
{
|
||||
Branch_stub_ent ent(object, to);
|
||||
typename Branch_stub_entries::const_iterator p
|
||||
@ -3281,6 +3424,37 @@ class Output_data_glink : public Output_section_data
|
||||
: Output_section_data(16), targ_(targ)
|
||||
{ }
|
||||
|
||||
void
|
||||
add_eh_frame(Layout* layout)
|
||||
{
|
||||
if (!parameters->options().ld_generated_unwind_info())
|
||||
return;
|
||||
|
||||
if (size == 64)
|
||||
layout->add_eh_frame_for_plt(this,
|
||||
Eh_cie<64>::eh_frame_cie,
|
||||
sizeof (Eh_cie<64>::eh_frame_cie),
|
||||
glink_eh_frame_fde_64,
|
||||
sizeof (glink_eh_frame_fde_64));
|
||||
else
|
||||
{
|
||||
// 32-bit .glink can use the default since the CIE return
|
||||
// address reg, LR, is valid.
|
||||
layout->add_eh_frame_for_plt(this,
|
||||
Eh_cie<32>::eh_frame_cie,
|
||||
sizeof (Eh_cie<32>::eh_frame_cie),
|
||||
default_fde,
|
||||
sizeof (default_fde));
|
||||
// Except where LR is used in a PIC __glink_PLTresolve.
|
||||
if (parameters->options().output_is_position_independent())
|
||||
layout->add_eh_frame_for_plt(this,
|
||||
Eh_cie<32>::eh_frame_cie,
|
||||
sizeof (Eh_cie<32>::eh_frame_cie),
|
||||
glink_eh_frame_fde_32,
|
||||
sizeof (glink_eh_frame_fde_32));
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// Write to a map file.
|
||||
void
|
||||
@ -4086,6 +4260,7 @@ Target_powerpc<size, big_endian>::make_glink_section(Layout* layout)
|
||||
if (this->glink_ == NULL)
|
||||
{
|
||||
this->glink_ = new Output_data_glink<size, big_endian>(this);
|
||||
this->glink_->add_eh_frame(layout);
|
||||
layout->add_output_section_data(".text", elfcpp::SHT_PROGBITS,
|
||||
elfcpp::SHF_ALLOC | elfcpp::SHF_EXECINSTR,
|
||||
this->glink_, ORDER_TEXT, false);
|
||||
|
@ -203,6 +203,15 @@ Target::set_view_to_nop(unsigned char* view, section_size_type view_size,
|
||||
}
|
||||
}
|
||||
|
||||
// Return address and size to plug into eh_frame FDEs associated with a PLT.
|
||||
void
|
||||
Target::do_plt_fde_location(const Output_data* plt, unsigned char*,
|
||||
uint64_t* address, off_t* len) const
|
||||
{
|
||||
*address = plt->address();
|
||||
*len = plt->data_size();
|
||||
}
|
||||
|
||||
// Class Sized_target.
|
||||
|
||||
// Set the EI_OSABI field of the ELF header if requested.
|
||||
|
@ -240,6 +240,12 @@ class Target
|
||||
adjust_elf_header(unsigned char* view, int len) const
|
||||
{ return this->do_adjust_elf_header(view, len); }
|
||||
|
||||
// Return address and size to plug into eh_frame FDEs associated with a PLT.
|
||||
void
|
||||
plt_fde_location(const Output_data* plt, unsigned char* oview,
|
||||
uint64_t* address, off_t* len) const
|
||||
{ return this->do_plt_fde_location(plt, oview, address, len); }
|
||||
|
||||
// Return whether NAME is a local label name. This is used to implement the
|
||||
// --discard-locals options.
|
||||
bool
|
||||
@ -530,6 +536,11 @@ class Target
|
||||
virtual void
|
||||
do_adjust_elf_header(unsigned char*, int) const = 0;
|
||||
|
||||
// Return address and size to plug into eh_frame FDEs associated with a PLT.
|
||||
virtual void
|
||||
do_plt_fde_location(const Output_data* plt, unsigned char* oview,
|
||||
uint64_t* address, off_t* len) const;
|
||||
|
||||
// Virtual function which may be overridden by the child class.
|
||||
virtual bool
|
||||
do_is_local_label_name(const char*) const;
|
||||
|
Loading…
Reference in New Issue
Block a user