mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-10 14:59:31 +08:00
Report linker script errors with line numbers. Ignore OUTPUT_FORMAT
with three arguments, and ignore OUTPUT_ARCH.
This commit is contained in:
@ -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()
|
Errors::initialize_lock()
|
||||||
{
|
{
|
||||||
if (this->lock_ == NULL)
|
if (this->lock_ == NULL && parameters->options_valid())
|
||||||
this->lock_ = new Lock;
|
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.
|
// Report a fatal error.
|
||||||
@ -73,11 +95,7 @@ Errors::error(const char* format, va_list args)
|
|||||||
vfprintf(stderr, format, args);
|
vfprintf(stderr, format, args);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
this->initialize_lock();
|
this->increment_counter(&this->error_count_);
|
||||||
{
|
|
||||||
Hold_lock h(*this->lock_);
|
|
||||||
++this->error_count_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report a warning.
|
// Report a warning.
|
||||||
@ -89,11 +107,7 @@ Errors::warning(const char* format, va_list args)
|
|||||||
vfprintf(stderr, format, args);
|
vfprintf(stderr, format, args);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
this->initialize_lock();
|
this->increment_counter(&this->warning_count_);
|
||||||
{
|
|
||||||
Hold_lock h(*this->lock_);
|
|
||||||
++this->warning_count_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report an error at a reloc location.
|
// 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);
|
vfprintf(stderr, format, args);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
this->initialize_lock();
|
this->increment_counter(&this->error_count_);
|
||||||
{
|
|
||||||
Hold_lock h(*this->lock_);
|
|
||||||
++this->error_count_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report a warning at a reloc location.
|
// 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);
|
vfprintf(stderr, format, args);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
|
|
||||||
this->initialize_lock();
|
this->increment_counter(&this->warning_count_);
|
||||||
{
|
|
||||||
Hold_lock h(*this->lock_);
|
|
||||||
++this->warning_count_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue an undefined symbol error.
|
// Issue an undefined symbol error.
|
||||||
@ -144,7 +150,8 @@ Errors::undefined_symbol(const Symbol* sym,
|
|||||||
const Relocate_info<size, big_endian>* relinfo,
|
const Relocate_info<size, big_endian>* relinfo,
|
||||||
size_t relnum, off_t reloffset)
|
size_t relnum, off_t reloffset)
|
||||||
{
|
{
|
||||||
this->initialize_lock();
|
bool initialized = this->initialize_lock();
|
||||||
|
gold_assert(initialized);
|
||||||
{
|
{
|
||||||
Hold_lock h(*this->lock_);
|
Hold_lock h(*this->lock_);
|
||||||
if (++this->undefined_symbols_[sym] >= max_undefined_error_report)
|
if (++this->undefined_symbols_[sym] >= max_undefined_error_report)
|
||||||
|
@ -95,10 +95,14 @@ class Errors
|
|||||||
|
|
||||||
// Initialize the lock. We don't do this in the constructor because
|
// Initialize the lock. We don't do this in the constructor because
|
||||||
// lock initialization wants to know whether we are using threads or
|
// lock initialization wants to know whether we are using threads or
|
||||||
// not.
|
// not. This returns true if the lock is now initialized.
|
||||||
void
|
bool
|
||||||
initialize_lock();
|
initialize_lock();
|
||||||
|
|
||||||
|
// Increment a counter, holding the lock.
|
||||||
|
void
|
||||||
|
increment_counter(int*);
|
||||||
|
|
||||||
// The number of times we report an undefined symbol.
|
// The number of times we report an undefined symbol.
|
||||||
static const int max_undefined_error_report = 5;
|
static const int max_undefined_error_report = 5;
|
||||||
|
|
||||||
|
@ -154,8 +154,7 @@ invoke_script(int argc, char** argv, char* arg, bool long_option,
|
|||||||
arg, long_option,
|
arg, long_option,
|
||||||
&ret);
|
&ret);
|
||||||
if (!read_commandline_script(script_name, cmdline))
|
if (!read_commandline_script(script_name, cmdline))
|
||||||
gold::gold_error(_("%s: unable to parse script file %s\n"),
|
gold::gold_error(_("unable to parse script file %s\n"), script_name);
|
||||||
gold::program_name, arg);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -881,7 +881,7 @@ class Parser_closure
|
|||||||
at_eof() const
|
at_eof() const
|
||||||
{ return this->next_token_index_ >= this->tokens_->size(); }
|
{ return this->next_token_index_ >= this->tokens_->size(); }
|
||||||
|
|
||||||
// Return the next token.
|
// Return the next token, and advance.
|
||||||
const Token*
|
const Token*
|
||||||
next_token()
|
next_token()
|
||||||
{
|
{
|
||||||
@ -890,6 +890,14 @@ class Parser_closure
|
|||||||
return ret;
|
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
|
// Return the list of input files, creating it if necessary. This
|
||||||
// is a space leak--we never free the INPUTS_ pointer.
|
// is a space leak--we never free the INPUTS_ pointer.
|
||||||
Input_arguments*
|
Input_arguments*
|
||||||
@ -1240,7 +1248,9 @@ yyerror(void* closurev, const char* message)
|
|||||||
{
|
{
|
||||||
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
|
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.
|
// Called by the bison parser to add a file to the link.
|
||||||
|
@ -168,14 +168,24 @@ file_list:
|
|||||||
|
|
||||||
/* A command which may appear at top level of a linker script. */
|
/* A command which may appear at top level of a linker script. */
|
||||||
file_cmd:
|
file_cmd:
|
||||||
OUTPUT_FORMAT '(' STRING ')'
|
GROUP
|
||||||
| GROUP
|
|
||||||
{ script_start_group(closure); }
|
{ script_start_group(closure); }
|
||||||
'(' input_list ')'
|
'(' input_list ')'
|
||||||
{ script_end_group(closure); }
|
{ script_end_group(closure); }
|
||||||
| OPTION '(' STRING ')'
|
| OPTION '(' STRING ')'
|
||||||
{ script_parse_option(closure, $3); }
|
{ script_parse_option(closure, $3); }
|
||||||
| file_or_sections_cmd
|
| 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. */
|
/* A list of input file names. */
|
||||||
|
Reference in New Issue
Block a user