* elfcpp_file.h: Fix header guard.  Include <cstdio>.
	(class Elf_recognizer): New class, code from gold/object.cc.
	(Elf_file::find_section_by_type): New method.
gold/:
	* incremental.cc: Include <cstdarg> and "target-select.h".
	(vexplain_no_incremental): New function.
	(explain_no_incremental): New function.
	(Incremental_binary::error): New method.
	(Sized_incremental_binary::do_find_incremental_inputs_section): New
	method.
	(make_sized_incremental_binary): New function.
	(open_incremental_binary): New function.
	(can_incrementally_link_file): Add checks if output is ELF and has
	inputs section.
	* incremental.h: Include "elfcpp_file.h" and "output.h".
	(Incremental_binary): New class.
	(Sized_incremental_binary): New class.
	(open_incremental_binary): Declare.
	* object.cc (is_elf_object): Use
	elfcpp::Elf_recognizer::is_elf_file.
	(make_elf_object): Use elfcpp::Elf_recognizer::is_valid_header.
	* output.h (Output_file::filesize): New method.
This commit is contained in:
Ian Lance Taylor
2009-10-09 16:40:51 +00:00
parent e322137b9b
commit c549a6949c
7 changed files with 513 additions and 63 deletions

View File

@@ -26,9 +26,11 @@
#include <map>
#include <vector>
#include "elfcpp_file.h"
#include "stringpool.h"
#include "workqueue.h"
#include "fileread.h"
#include "output.h"
namespace gold
{
@@ -50,6 +52,117 @@ enum Incremental_input_type
INCREMENTAL_INPUT_SCRIPT = 4
};
// An object representing the ELF file we edit during an incremental build.
// Similar to Object or Dynobj, but operates on Output_file and contains
// method specific to file edition (TBD). This is the abstract parent class
// implemented in Sized_incremental_binary<size, big_endian> for a specific
// endianness and size.
class Incremental_binary
{
public:
Incremental_binary(Output_file* output, Target* target)
: output_(output), target_(target)
{ }
virtual
~Incremental_binary()
{ }
// Functions and types for the elfcpp::Elf_file interface. This
// permit us to use Incremental_binary as the File template parameter for
// elfcpp::Elf_file.
// The View class is returned by view. It must support a single
// method, data(). This is trivial, because Output_file::get_output_view
// does what we need.
class View
{
public:
View(const unsigned char* p)
: p_(p)
{ }
const unsigned char*
data() const
{ return this->p_; }
private:
const unsigned char* p_;
};
// Return a View.
View
view(off_t file_offset, section_size_type data_size)
{ return View(this->output_->get_input_view(file_offset, data_size)); }
// A location in the file.
struct Location
{
off_t file_offset;
off_t data_size;
Location(off_t fo, section_size_type ds)
: file_offset(fo), data_size(ds)
{ }
Location()
: file_offset(0), data_size(0)
{ }
};
// Get a View given a Location.
View view(Location loc)
{ return View(this->view(loc.file_offset, loc.data_size)); }
// Report an error.
void
error(const char* format, ...) const ATTRIBUTE_PRINTF_2;
// Find the .gnu_incremental_inputs section. It selects the first section
// of type SHT_GNU_INCREMENTAL_INPUTS. Returns false if such a section
// is not found.
bool
find_incremental_inputs_section(Location* location)
{ return do_find_incremental_inputs_section(location); }
protected:
// Find incremental inputs section.
virtual bool
do_find_incremental_inputs_section(Location* location) = 0;
private:
// Edited output file object.
Output_file* output_;
// Target of the output file.
Target* target_;
};
template<int size, bool big_endian>
class Sized_incremental_binary : public Incremental_binary
{
public:
Sized_incremental_binary(Output_file* output,
const elfcpp::Ehdr<size, big_endian>& ehdr,
Target* target)
: Incremental_binary(output, target), elf_file_(this, ehdr)
{ }
protected:
virtual bool
do_find_incremental_inputs_section(Location* location);
private:
// Output as an ELF file.
elfcpp::Elf_file<size, big_endian, Incremental_binary> elf_file_;
};
// Create an Incremental_binary object for FILE. Returns NULL is this is not
// possible, e.g. FILE is not an ELF file or has an unsupported target.
Incremental_binary*
open_incremental_binary(Output_file* file);
// Code invoked early during an incremental link that checks what files need
// to be relinked.
class Incremental_checker