Report linker script errors with line numbers. Ignore OUTPUT_FORMAT

with three arguments, and ignore OUTPUT_ARCH.
This commit is contained in:
Ian Lance Taylor 2008-01-07 05:19:02 +00:00
parent d4e917ea7f
commit 2dd3e587bd
5 changed files with 62 additions and 32 deletions

View File

@ -44,13 +44,35 @@ Errors::Errors(const char* program_name)
{
}
// Initialize the lock_ field.
// Initialize the lock_ field. If we have not yet processed the
// parameters, then we can't initialize, since we don't yet know
// whether we are using threads. That is OK, since if we haven't
// processed the parameters, we haven't created any threads, and we
// don't need a lock. Return true if the lock is now initialized.
void
bool
Errors::initialize_lock()
{
if (this->lock_ == NULL)
if (this->lock_ == NULL && parameters->options_valid())
this->lock_ = new Lock;
return this->lock_ != NULL;
}
// Increment a counter, holding the lock if available.
void
Errors::increment_counter(int *counter)
{
if (!this->initialize_lock())
{
// The lock does not exist, which means that we don't need it.
++*counter;
}
else
{
Hold_lock h(*this->lock_);
++*counter;
}
}
// Report a fatal error.
@ -73,11 +95,7 @@ Errors::error(const char* format, va_list args)
vfprintf(stderr, format, args);
fputc('\n', stderr);
this->initialize_lock();
{
Hold_lock h(*this->lock_);
++this->error_count_;
}
this->increment_counter(&this->error_count_);
}
// Report a warning.
@ -89,11 +107,7 @@ Errors::warning(const char* format, va_list args)
vfprintf(stderr, format, args);
fputc('\n', stderr);
this->initialize_lock();
{
Hold_lock h(*this->lock_);
++this->warning_count_;
}
this->increment_counter(&this->warning_count_);
}
// Report an error at a reloc location.
@ -109,11 +123,7 @@ Errors::error_at_location(const Relocate_info<size, big_endian>* relinfo,
vfprintf(stderr, format, args);
fputc('\n', stderr);
this->initialize_lock();
{
Hold_lock h(*this->lock_);
++this->error_count_;
}
this->increment_counter(&this->error_count_);
}
// Report a warning at a reloc location.
@ -129,11 +139,7 @@ Errors::warning_at_location(const Relocate_info<size, big_endian>* relinfo,
vfprintf(stderr, format, args);
fputc('\n', stderr);
this->initialize_lock();
{
Hold_lock h(*this->lock_);
++this->warning_count_;
}
this->increment_counter(&this->warning_count_);
}
// Issue an undefined symbol error.
@ -144,7 +150,8 @@ Errors::undefined_symbol(const Symbol* sym,
const Relocate_info<size, big_endian>* relinfo,
size_t relnum, off_t reloffset)
{
this->initialize_lock();
bool initialized = this->initialize_lock();
gold_assert(initialized);
{
Hold_lock h(*this->lock_);
if (++this->undefined_symbols_[sym] >= max_undefined_error_report)

View File

@ -95,10 +95,14 @@ class Errors
// Initialize the lock. We don't do this in the constructor because
// lock initialization wants to know whether we are using threads or
// not.
void
// not. This returns true if the lock is now initialized.
bool
initialize_lock();
// Increment a counter, holding the lock.
void
increment_counter(int*);
// The number of times we report an undefined symbol.
static const int max_undefined_error_report = 5;

View File

@ -154,8 +154,7 @@ invoke_script(int argc, char** argv, char* arg, bool long_option,
arg, long_option,
&ret);
if (!read_commandline_script(script_name, cmdline))
gold::gold_error(_("%s: unable to parse script file %s\n"),
gold::program_name, arg);
gold::gold_error(_("unable to parse script file %s\n"), script_name);
return ret;
}

View File

@ -881,7 +881,7 @@ class Parser_closure
at_eof() const
{ return this->next_token_index_ >= this->tokens_->size(); }
// Return the next token.
// Return the next token, and advance.
const Token*
next_token()
{
@ -890,6 +890,14 @@ class Parser_closure
return ret;
}
// Return the previous token.
const Token*
last_token() const
{
gold_assert(this->next_token_index_ > 0);
return &(*this->tokens_)[this->next_token_index_ - 1];
}
// Return the list of input files, creating it if necessary. This
// is a space leak--we never free the INPUTS_ pointer.
Input_arguments*
@ -1240,7 +1248,9 @@ yyerror(void* closurev, const char* message)
{
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
gold_error(_("%s: %s"), closure->filename(), message);
const Token* token = closure->last_token();
gold_error(_("%s:%d:%d: %s"), closure->filename(), token->lineno(),
token->charpos(), message);
}
// Called by the bison parser to add a file to the link.

View File

@ -168,14 +168,24 @@ file_list:
/* A command which may appear at top level of a linker script. */
file_cmd:
OUTPUT_FORMAT '(' STRING ')'
| GROUP
GROUP
{ script_start_group(closure); }
'(' input_list ')'
{ script_end_group(closure); }
| OPTION '(' STRING ')'
{ script_parse_option(closure, $3); }
| file_or_sections_cmd
| ignore_cmd
;
/* Top level commands which we ignore. The GNU linker uses these to
select the output format, but we don't offer a choice. Ignoring
these is more-or-less OK since most scripts simply explicitly
choose the default. */
ignore_cmd:
OUTPUT_FORMAT '(' STRING ')'
| OUTPUT_FORMAT '(' STRING ',' STRING ',' STRING ')'
| OUTPUT_ARCH '(' STRING ')'
;
/* A list of input file names. */