From d391083d3c938e56a0d0f3e03867d91369198d35 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Sun, 6 Jan 2008 00:47:10 +0000 Subject: Add support for -e and for ENTRY in linker scripts. --- gold/output.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 15 deletions(-) (limited to 'gold/output.cc') diff --git a/gold/output.cc b/gold/output.cc index 0e28629..4c6959e 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -294,12 +294,14 @@ Output_segment_headers::do_sized_write(Output_file* of) Output_file_header::Output_file_header(const Target* target, const Symbol_table* symtab, - const Output_segment_headers* osh) + const Output_segment_headers* osh, + const char* entry) : target_(target), symtab_(symtab), segment_header_(osh), section_header_(NULL), - shstrtab_(NULL) + shstrtab_(NULL), + entry_(entry) { const int size = parameters->get_size(); int ehdr_size; @@ -415,19 +417,7 @@ Output_file_header::do_sized_write(Output_file* of) oehdr.put_e_machine(this->target_->machine_code()); oehdr.put_e_version(elfcpp::EV_CURRENT); - // FIXME: Need to support -e, and target specific entry symbol. - Symbol* sym = this->symtab_->lookup("_start"); - typename Sized_symbol::Value_type v; - if (sym == NULL) - v = 0; - else - { - Sized_symbol* ssym; - ssym = this->symtab_->get_sized_symbol SELECT_SIZE_NAME(size) ( - sym SELECT_SIZE(size)); - v = ssym->value(); - } - oehdr.put_e_entry(v); + oehdr.put_e_entry(this->entry()); oehdr.put_e_phoff(this->segment_header_->offset()); oehdr.put_e_shoff(this->section_header_->offset()); @@ -447,6 +437,49 @@ Output_file_header::do_sized_write(Output_file* of) of->write_output_view(0, ehdr_size, view); } +// Return the value to use for the entry address. THIS->ENTRY_ is the +// symbol specified on the command line, if any. + +template +typename elfcpp::Elf_types::Elf_Addr +Output_file_header::entry() +{ + const bool should_issue_warning = (this->entry_ != NULL + && parameters->output_is_executable()); + + // FIXME: Need to support target specific entry symbol. + const char* entry = this->entry_; + if (entry == NULL) + entry = "_start"; + + Symbol* sym = this->symtab_->lookup(entry); + + typename Sized_symbol::Value_type v; + if (sym != NULL) + { + Sized_symbol* ssym; + ssym = this->symtab_->get_sized_symbol(sym); + if (!ssym->is_defined() && should_issue_warning) + gold_warning("entry symbol '%s' exists but is not defined", entry); + v = ssym->value(); + } + else + { + // We couldn't find the entry symbol. See if we can parse it as + // a number. This supports, e.g., -e 0x1000. + char* endptr; + v = strtoull(entry, &endptr, 0); + if (*endptr != '\0') + { + if (should_issue_warning) + gold_warning("cannot find entry symbol '%s'", entry); + v = 0; + } + } + + return v; +} + // Output_data_const methods. void -- cgit v1.1