This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: gold cannot handle _start in a library
- From: Ian Lance Taylor <iant at google dot com>
- To: Roland McGrath <mcgrathr at google dot com>
- Cc: bug-binutils at gnu dot org, binutils at sourceware dot org
- Date: Tue, 24 May 2011 17:17:51 -0700
- Subject: Re: gold cannot handle _start in a library
- References: <x57jd3j7vfp1.fsf@frobland.mtv.corp.google.com>
Roland McGrath <mcgrathr@google.com> writes:
> Given:
>
> $ gcc -c -xc <(echo '_start(){}') -o start.o
> $ ar cq libstart.a start.o
> $ ./gold/ld-new -o foo libstart.a
>
> The output file foo is an empty ELF file.
> With:
>
> $ ./gold/ld-new -o foo -e _start libstart.a
> ./gold/ld-new: warning: cannot find entry symbol '_start'
>
> The results are the same, plus the extra warning.
>
> BFD ld does not have this bug.
> I tested with today's trunk builds of gold and BFD ld.
Thanks. Fixed like so. Committed to mainline.
Ian
2011-05-24 Ian Lance Taylor <iant@google.com>
* archive.cc (Library_base::should_include_member): Pull in object
from archive if it defines the entry symbol.
* parameters.cc (Parameters::entry): New function.
* parameters.h (class Parameters): Declare entry.
* output.h (class Output_file_header): Remove entry_ field.
* output.cc (Output_file_header::Output_file_header): Remove entry
parameter. Change all callers.
(Output_file_header::entry): Use parameters->entry.
* gold.cc (queue_middle_tasks): Likewise.
* plugin.cc (Plugin_hook::run): Likewise.
Index: archive.cc
===================================================================
RCS file: /cvs/src/src/gold/archive.cc,v
retrieving revision 1.67
diff -p -u -r1.67 archive.cc
--- archive.cc 12 Apr 2011 00:44:47 -0000 1.67
+++ archive.cc 25 May 2011 00:11:15 -0000
@@ -113,6 +113,11 @@ Library_base::should_include_member(Symb
*why = buf;
delete[] buf;
}
+ else if (strcmp(sym_name, parameters->entry()) == 0)
+ {
+ *why = "entry symbol ";
+ *why += sym_name;
+ }
else
return Library_base::SHOULD_INCLUDE_UNKNOWN;
}
Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.89
diff -p -u -r1.89 gold.cc
--- gold.cc 24 May 2011 23:31:06 -0000 1.89
+++ gold.cc 25 May 2011 00:11:15 -0000
@@ -501,11 +501,7 @@ queue_middle_tasks(const General_options
if (parameters->options().gc_sections())
{
// Find the start symbol if any.
- Symbol* start_sym;
- if (parameters->options().entry())
- start_sym = symtab->lookup(parameters->options().entry());
- else
- start_sym = symtab->lookup("_start");
+ Symbol* start_sym = symtab->lookup(parameters->entry());
if (start_sym != NULL)
{
bool is_ordinary;
Index: layout.cc
===================================================================
RCS file: /cvs/src/src/gold/layout.cc,v
retrieving revision 1.196
diff -p -u -r1.196 layout.cc
--- layout.cc 24 May 2011 21:57:28 -0000 1.196
+++ layout.cc 25 May 2011 00:11:17 -0000
@@ -2192,9 +2192,8 @@ Layout::finalize(const Input_objects* in
: new Output_segment_headers(this->segment_list_));
// Lay out the file header.
- Output_file_header* file_header
- = new Output_file_header(target, symtab, segment_headers,
- parameters->options().entry());
+ Output_file_header* file_header = new Output_file_header(target, symtab,
+ segment_headers);
this->special_output_list_.push_back(file_header);
if (segment_headers != NULL)
Index: output.h
===================================================================
RCS file: /cvs/src/src/gold/output.h,v
retrieving revision 1.123
diff -p -u -r1.123 output.h
--- output.h 24 May 2011 23:31:07 -0000 1.123
+++ output.h 25 May 2011 00:11:19 -0000
@@ -566,8 +566,7 @@ class Output_file_header : public Output
public:
Output_file_header(const Target*,
const Symbol_table*,
- const Output_segment_headers*,
- const char* entry);
+ const Output_segment_headers*);
// Add information about the section headers. We lay out the ELF
// file header before we create the section headers.
@@ -614,7 +613,6 @@ class Output_file_header : public Output
const Output_segment_headers* segment_header_;
const Output_section_headers* section_header_;
const Output_section* shstrtab_;
- const char* entry_;
};
// Output sections are mainly comprised of input sections. However,
Index: output.cc
===================================================================
RCS file: /cvs/src/src/gold/output.cc,v
retrieving revision 1.146
diff -p -u -r1.146 output.cc
--- output.cc 24 May 2011 23:31:07 -0000 1.146
+++ output.cc 25 May 2011 00:11:21 -0000
@@ -425,14 +425,12 @@ Output_segment_headers::do_size() const
Output_file_header::Output_file_header(const Target* target,
const Symbol_table* symtab,
- const Output_segment_headers* osh,
- const char* entry)
+ const Output_segment_headers* osh)
: target_(target),
symtab_(symtab),
segment_header_(osh),
section_header_(NULL),
- shstrtab_(NULL),
- entry_(entry)
+ shstrtab_(NULL)
{
this->set_data_size(this->do_size());
}
@@ -572,22 +570,16 @@ Output_file_header::do_sized_write(Outpu
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.
+// Return the value to use for the entry address.
template<int size>
typename elfcpp::Elf_types<size>::Elf_Addr
Output_file_header::entry()
{
- const bool should_issue_warning = (this->entry_ != NULL
+ const bool should_issue_warning = (parameters->options().entry() != NULL
&& !parameters->options().relocatable()
&& !parameters->options().shared());
-
- // FIXME: Need to support target specific entry symbol.
- const char* entry = this->entry_;
- if (entry == NULL)
- entry = "_start";
-
+ const char* entry = parameters->entry();
Symbol* sym = this->symtab_->lookup(entry);
typename Sized_symbol<size>::Value_type v;
Index: parameters.cc
===================================================================
RCS file: /cvs/src/src/gold/parameters.cc,v
retrieving revision 1.34
diff -p -u -r1.34 parameters.cc
--- parameters.cc 14 Oct 2010 22:10:22 -0000 1.34
+++ parameters.cc 25 May 2011 00:11:21 -0000
@@ -211,6 +211,20 @@ Parameters::check_target_endianness()
}
}
+// Return the name of the entry symbol.
+
+const char*
+Parameters::entry() const
+{
+ const char* ret = this->options().entry();
+ if (ret == NULL)
+ {
+ // FIXME: Need to support target specific entry symbol.
+ ret = "_start";
+ }
+ return ret;
+}
+
// Set the incremental linking mode to INCREMENTAL_FULL. Used when
// the linker determines that an incremental update is not possible.
// Returns false if the incremental mode was INCREMENTAL_UPDATE,
Index: parameters.h
===================================================================
RCS file: /cvs/src/src/gold/parameters.h,v
retrieving revision 1.30
diff -p -u -r1.30 parameters.h
--- parameters.h 14 Oct 2010 22:10:22 -0000 1.30
+++ parameters.h 25 May 2011 00:11:21 -0000
@@ -134,6 +134,10 @@ class Parameters
return debug_;
}
+ // Return the name of the entry symbol.
+ const char*
+ entry() const;
+
// A convenience routine for combining size and endianness. It also
// checks the HAVE_TARGET_FOO configure options and dies if the
// current target's size/endianness is not supported according to
Index: plugin.cc
===================================================================
RCS file: /cvs/src/src/gold/plugin.cc,v
retrieving revision 1.46
diff -p -u -r1.46 plugin.cc
--- plugin.cc 12 Apr 2011 00:44:48 -0000 1.46
+++ plugin.cc 25 May 2011 00:11:21 -0000
@@ -1218,11 +1218,7 @@ void
Plugin_hook::run(Workqueue* workqueue)
{
gold_assert(this->options_.has_plugins());
- Symbol* start_sym;
- if (parameters->options().entry())
- start_sym = this->symtab_->lookup(parameters->options().entry());
- else
- start_sym = this->symtab_->lookup("_start");
+ Symbol* start_sym = this->symtab_->lookup(parameters->entry());
if (start_sym != NULL)
start_sym->set_in_real_elf();