#ifndef GOLD_TARGET_H
#define GOLD_TARGET_H
-#include "symtab.h"
#include "elfcpp.h"
namespace gold
{
+class General_options;
class Object;
+template<int size, bool big_endian>
+class Sized_relobj;
+template<int size, bool big_endian>
+struct Relocate_info;
+class Symbol;
+template<int size>
+class Sized_symbol;
+class Symbol_table;
// The abstract class for target specific handling.
// return 32 or 64.
int
get_size() const
- { return this->size_; }
+ { return this->pti_->size; }
// Return whether this target is big-endian.
bool
is_big_endian() const
- { return this->is_big_endian_; }
+ { return this->pti_->is_big_endian; }
+
+ // Machine code to store in e_machine field of ELF header.
+ elfcpp::EM
+ machine_code() const
+ { return this->pti_->machine_code; }
// Whether this target has a specific make_symbol function.
bool
has_make_symbol() const
- { return this->has_make_symbol_; }
+ { return this->pti_->has_make_symbol; }
// Whether this target has a specific resolve function.
bool
has_resolve() const
- { return this->has_resolve_; }
+ { return this->pti_->has_resolve; }
+
+ // Return the default name of the dynamic linker.
+ const char*
+ dynamic_linker() const
+ { return this->pti_->dynamic_linker; }
+
+ // Return the default address to use for the text segment.
+ uint64_t
+ text_segment_address() const
+ { return this->pti_->text_segment_address; }
+
+ // Return the ABI specified page size.
+ uint64_t
+ abi_pagesize() const
+ { return this->pti_->abi_pagesize; }
+
+ // Return the common page size used on actual systems.
+ uint64_t
+ common_pagesize() const
+ { return this->pti_->common_pagesize; }
+
+ // This is called to tell the target to complete any sections it is
+ // handling. After this all sections must have their final size.
+ void
+ finalize_sections(const General_options* options, Layout* layout)
+ { return this->do_finalize_sections(options, layout); }
protected:
- Target(int size, bool is_big_endian, bool has_make_symbol, bool has_resolve)
- : size_(size),
- is_big_endian_(is_big_endian),
- has_make_symbol_(has_make_symbol),
- has_resolve_(has_resolve)
+ // This struct holds the constant information for a child class. We
+ // use a struct to avoid the overhead of virtual function calls for
+ // simple information.
+ struct Target_info
+ {
+ // Address size (32 or 64).
+ int size;
+ // Whether the target is big endian.
+ bool is_big_endian;
+ // The code to store in the e_machine field of the ELF header.
+ elfcpp::EM machine_code;
+ // Whether this target has a specific make_symbol function.
+ bool has_make_symbol;
+ // Whether this target has a specific resolve function.
+ bool has_resolve;
+ // The default dynamic linker name.
+ const char* dynamic_linker;
+ // The default text segment address.
+ uint64_t text_segment_address;
+ // The ABI specified page size.
+ uint64_t abi_pagesize;
+ // The common page size used by actual implementations.
+ uint64_t common_pagesize;
+ };
+
+ Target(const Target_info* pti)
+ : pti_(pti)
+ { }
+
+ // Virtual function which may be implemented by the child class.
+ virtual void
+ do_finalize_sections(const General_options*, Layout*)
{ }
private:
Target(const Target&);
Target& operator=(const Target&);
- // The target size.
- int size_;
- // Whether this target is big endian.
- bool is_big_endian_;
- // Whether this target has a special make_symbol function.
- bool has_make_symbol_;
- // Whether this target has a special resolve function.
- bool has_resolve_;
+ // The target information.
+ const Target_info* pti_;
};
// The abstract class for a specific size and endianness of target.
// symbol table. This will only be called if has_make_symbol()
// returns true.
virtual Sized_symbol<size>*
- make_symbol()
- { abort(); }
+ make_symbol() const
+ { gold_unreachable(); }
// Resolve a symbol for the target. This should be overridden by a
// target which needs to take special action. TO is the
// pre-existing symbol. SYM is the new symbol, seen in OBJECT.
+ // VERSION is the version of SYM. This will only be called if
+ // has_resolve() returns true.
+ virtual void
+ resolve(Symbol*, const elfcpp::Sym<size, big_endian>&, Object*,
+ const char*)
+ { gold_unreachable(); }
+
+ // Scan the relocs for a section, and record any information
+ // required for the symbol. OPTIONS is the command line options.
+ // SYMTAB is the symbol table. OBJECT is the object in which the
+ // section appears. DATA_SHNDX is the section index that these
+ // relocs apply to. SH_TYPE is the type of the relocation section,
+ // SHT_REL or SHT_RELA. PRELOCS points to the relocation data.
+ // RELOC_COUNT is the number of relocs. LOCAL_SYMBOL_COUNT is the
+ // number of local symbols. PLOCAL_SYMBOLS points to the local
+ // symbol data from OBJECT. GLOBAL_SYMBOLS is the array of pointers
+ // to the global symbol table from OBJECT.
virtual void
- resolve(Symbol*, const elfcpp::Sym<size, big_endian>&, Object*)
- { abort(); }
+ scan_relocs(const General_options& options,
+ Symbol_table* symtab,
+ Layout* layout,
+ Sized_relobj<size, big_endian>* object,
+ unsigned int data_shndx,
+ unsigned int sh_type,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ size_t local_symbol_count,
+ const unsigned char* plocal_symbols,
+ Symbol** global_symbols) = 0;
+
+ // Relocate section data. SH_TYPE is the type of the relocation
+ // section, SHT_REL or SHT_RELA. PRELOCS points to the relocation
+ // information. RELOC_COUNT is the number of relocs. VIEW is a
+ // view into the output file holding the section contents,
+ // VIEW_ADDRESS is the virtual address of the view, and VIEW_SIZE is
+ // the size of the view.
+ virtual void
+ relocate_section(const Relocate_info<size, big_endian>*,
+ unsigned int sh_type,
+ const unsigned char* prelocs,
+ size_t reloc_count,
+ unsigned char* view,
+ typename elfcpp::Elf_types<size>::Elf_Addr view_address,
+ off_t view_size) = 0;
protected:
- Sized_target(bool has_make_symbol, bool has_resolve)
- : Target(size, big_endian, has_make_symbol, has_resolve)
- { }
+ Sized_target(const Target::Target_info* pti)
+ : Target(pti)
+ {
+ gold_assert(pti->size == size);
+ gold_assert(pti->is_big_endian ? big_endian : !big_endian);
+ }
};
} // End namespace gold.