* common.cc (Symbol_table::do_allocate_commons_list): Call
gold_fallback. * errors.cc (Errors::fatal): Adjust call to gold_exit. (Errors::fallback): New function. (gold_fallback): New function. * errors.h (Errors::fallback): New function. * gold.cc (gold_exit): Change status parameter to enum; adjust all callers. (queue_initial_tasks): Call gold_fallback. * gold.h: Include cstdlib. (Exit_status): New enum type. (gold_exit): Change status parameter to enum. (gold_fallback): New function. * layout.cc (Layout::set_section_offsets): Call gold_fallback. (Layout::create_symtab_sections): Likewise. (Layout::create_shdrs): Likewise. * main.cc (main): Adjust call to gold_exit. * output.cc (Output_data_got::add_got_entry): Call gold_fallback. (Output_data_got::add_got_entry_pair): Likewise. (Output_section::add_input_section): Likewise. (Output_section::add_output_section_data): Likewise. (Output_segment::set_section_list_addresses): Likewise. * x86_64.cc (Output_data_plt_x86_64::add_entry): Likewise.
This commit is contained in:
parent
fb0e076f5c
commit
e6455dfbc2
@ -1,3 +1,29 @@
|
|||||||
|
2011-06-07 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
|
* common.cc (Symbol_table::do_allocate_commons_list): Call
|
||||||
|
gold_fallback.
|
||||||
|
* errors.cc (Errors::fatal): Adjust call to gold_exit.
|
||||||
|
(Errors::fallback): New function.
|
||||||
|
(gold_fallback): New function.
|
||||||
|
* errors.h (Errors::fallback): New function.
|
||||||
|
* gold.cc (gold_exit): Change status parameter to enum; adjust
|
||||||
|
all callers.
|
||||||
|
(queue_initial_tasks): Call gold_fallback.
|
||||||
|
* gold.h: Include cstdlib.
|
||||||
|
(Exit_status): New enum type.
|
||||||
|
(gold_exit): Change status parameter to enum.
|
||||||
|
(gold_fallback): New function.
|
||||||
|
* layout.cc (Layout::set_section_offsets): Call gold_fallback.
|
||||||
|
(Layout::create_symtab_sections): Likewise.
|
||||||
|
(Layout::create_shdrs): Likewise.
|
||||||
|
* main.cc (main): Adjust call to gold_exit.
|
||||||
|
* output.cc (Output_data_got::add_got_entry): Call gold_fallback.
|
||||||
|
(Output_data_got::add_got_entry_pair): Likewise.
|
||||||
|
(Output_section::add_input_section): Likewise.
|
||||||
|
(Output_section::add_output_section_data): Likewise.
|
||||||
|
(Output_segment::set_section_list_addresses): Likewise.
|
||||||
|
* x86_64.cc (Output_data_plt_x86_64::add_entry): Likewise.
|
||||||
|
|
||||||
2011-06-07 Cary Coutant <ccoutant@google.com>
|
2011-06-07 Cary Coutant <ccoutant@google.com>
|
||||||
|
|
||||||
* layout.cc (Layout::set_segment_offsets): Don't adjust layout
|
* layout.cc (Layout::set_segment_offsets): Don't adjust layout
|
||||||
|
@ -351,9 +351,9 @@ Symbol_table::do_allocate_commons_list(
|
|||||||
// For an incremental update, allocate from the free list.
|
// For an incremental update, allocate from the free list.
|
||||||
off = os->allocate(ssym->symsize(), ssym->value());
|
off = os->allocate(ssym->symsize(), ssym->value());
|
||||||
if (off == -1)
|
if (off == -1)
|
||||||
gold_fatal(_("out of patch space in section %s; "
|
gold_fallback(_("out of patch space in section %s; "
|
||||||
"relink with --incremental-full"),
|
"relink with --incremental-full"),
|
||||||
os->name());
|
os->name());
|
||||||
ssym->allocate_common(os, off);
|
ssym->allocate_common(os, off);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,18 @@ Errors::fatal(const char* format, va_list args)
|
|||||||
fprintf(stderr, _("%s: fatal error: "), this->program_name_);
|
fprintf(stderr, _("%s: fatal error: "), this->program_name_);
|
||||||
vfprintf(stderr, format, args);
|
vfprintf(stderr, format, args);
|
||||||
fputc('\n', stderr);
|
fputc('\n', stderr);
|
||||||
gold_exit(false);
|
gold_exit(GOLD_ERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report a fallback error.
|
||||||
|
|
||||||
|
void
|
||||||
|
Errors::fallback(const char* format, va_list args)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("%s: fatal error: "), this->program_name_);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
fputc('\n', stderr);
|
||||||
|
gold_exit(GOLD_FALLBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report an error.
|
// Report an error.
|
||||||
@ -212,6 +223,17 @@ gold_fatal(const char* format, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report a fallback error.
|
||||||
|
|
||||||
|
void
|
||||||
|
gold_fallback(const char* format, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
parameters->errors()->fallback(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
// Report an error.
|
// Report an error.
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -49,6 +49,12 @@ class Errors
|
|||||||
void
|
void
|
||||||
fatal(const char* format, va_list) ATTRIBUTE_NORETURN;
|
fatal(const char* format, va_list) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
|
// Report a fallback error. After printing the error, this must exit
|
||||||
|
// with a special status code indicating that fallback to
|
||||||
|
// --incremental-full is required.
|
||||||
|
void
|
||||||
|
fallback(const char* format, va_list) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
// Report an error and continue.
|
// Report an error and continue.
|
||||||
void
|
void
|
||||||
error(const char* format, va_list);
|
error(const char* format, va_list);
|
||||||
|
16
gold/gold.cc
16
gold/gold.cc
@ -58,15 +58,15 @@ process_incremental_input(Incremental_binary*, unsigned int, Input_objects*,
|
|||||||
Task_token*, Task_token*);
|
Task_token*, Task_token*);
|
||||||
|
|
||||||
void
|
void
|
||||||
gold_exit(bool status)
|
gold_exit(Exit_status status)
|
||||||
{
|
{
|
||||||
if (parameters != NULL
|
if (parameters != NULL
|
||||||
&& parameters->options_valid()
|
&& parameters->options_valid()
|
||||||
&& parameters->options().has_plugins())
|
&& parameters->options().has_plugins())
|
||||||
parameters->options().plugins()->cleanup();
|
parameters->options().plugins()->cleanup();
|
||||||
if (!status && parameters != NULL && parameters->options_valid())
|
if (status != GOLD_OK && parameters != NULL && parameters->options_valid())
|
||||||
unlink_if_ordinary(parameters->options().output_file_name());
|
unlink_if_ordinary(parameters->options().output_file_name());
|
||||||
exit(status ? EXIT_SUCCESS : EXIT_FAILURE);
|
exit(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -87,7 +87,7 @@ gold_nomem()
|
|||||||
const char* const s = ": out of memory\n";
|
const char* const s = ": out of memory\n";
|
||||||
len = write(2, s, strlen(s));
|
len = write(2, s, strlen(s));
|
||||||
}
|
}
|
||||||
gold_exit(false);
|
gold_exit(GOLD_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle an unreachable case.
|
// Handle an unreachable case.
|
||||||
@ -97,7 +97,7 @@ do_gold_unreachable(const char* filename, int lineno, const char* function)
|
|||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: internal error in %s, at %s:%d\n"),
|
fprintf(stderr, _("%s: internal error in %s, at %s:%d\n"),
|
||||||
program_name, function, filename, lineno);
|
program_name, function, filename, lineno);
|
||||||
gold_exit(false);
|
gold_exit(GOLD_ERR);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class arranges to run the functions done in the middle of the
|
// This class arranges to run the functions done in the middle of the
|
||||||
@ -176,7 +176,7 @@ queue_initial_tasks(const General_options& options,
|
|||||||
if (cmdline.begin() == cmdline.end())
|
if (cmdline.begin() == cmdline.end())
|
||||||
{
|
{
|
||||||
if (options.printed_version())
|
if (options.printed_version())
|
||||||
gold_exit(true);
|
gold_exit(GOLD_OK);
|
||||||
gold_fatal(_("no input files"));
|
gold_fatal(_("no input files"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,7 @@ queue_initial_tasks(const General_options& options,
|
|||||||
if (set_parameters_incremental_full())
|
if (set_parameters_incremental_full())
|
||||||
gold_info(_("linking with --incremental-full"));
|
gold_info(_("linking with --incremental-full"));
|
||||||
else
|
else
|
||||||
gold_fatal(_("restart link with --incremental-full"));
|
gold_fallback(_("restart link with --incremental-full"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -748,7 +748,7 @@ queue_middle_tasks(const General_options& options,
|
|||||||
// THIS_BLOCKER to be NULL here. There's no real point in
|
// THIS_BLOCKER to be NULL here. There's no real point in
|
||||||
// continuing if that happens.
|
// continuing if that happens.
|
||||||
gold_assert(parameters->errors()->error_count() > 0);
|
gold_assert(parameters->errors()->error_count() > 0);
|
||||||
gold_exit(false);
|
gold_exit(GOLD_ERR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
gold/gold.h
19
gold/gold.h
@ -27,6 +27,7 @@
|
|||||||
#include "ansidecl.h"
|
#include "ansidecl.h"
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -166,6 +167,15 @@ class Output_file;
|
|||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
struct Relocate_info;
|
struct Relocate_info;
|
||||||
|
|
||||||
|
// Exit status codes.
|
||||||
|
|
||||||
|
enum Exit_status
|
||||||
|
{
|
||||||
|
GOLD_OK = EXIT_SUCCESS,
|
||||||
|
GOLD_ERR = EXIT_FAILURE,
|
||||||
|
GOLD_FALLBACK = EXIT_FAILURE + 1
|
||||||
|
};
|
||||||
|
|
||||||
// Some basic types. For these we use lower case initial letters.
|
// Some basic types. For these we use lower case initial letters.
|
||||||
|
|
||||||
// For an offset in an input or output file, use off_t. Note that
|
// For an offset in an input or output file, use off_t. Note that
|
||||||
@ -183,7 +193,7 @@ extern const char* program_name;
|
|||||||
// This function is called to exit the program. Status is true to
|
// This function is called to exit the program. Status is true to
|
||||||
// exit success (0) and false to exit failure (1).
|
// exit success (0) and false to exit failure (1).
|
||||||
extern void
|
extern void
|
||||||
gold_exit(bool status) ATTRIBUTE_NORETURN;
|
gold_exit(Exit_status status) ATTRIBUTE_NORETURN;
|
||||||
|
|
||||||
// This function is called to emit an error message and then
|
// This function is called to emit an error message and then
|
||||||
// immediately exit with failure.
|
// immediately exit with failure.
|
||||||
@ -203,6 +213,13 @@ gold_warning(const char* msg, ...) ATTRIBUTE_PRINTF_1;
|
|||||||
extern void
|
extern void
|
||||||
gold_info(const char* msg, ...) ATTRIBUTE_PRINTF_1;
|
gold_info(const char* msg, ...) ATTRIBUTE_PRINTF_1;
|
||||||
|
|
||||||
|
// This function is called to emit an error message and then
|
||||||
|
// immediately exit with fallback status (e.g., when
|
||||||
|
// --incremental-update fails and the link needs to be restarted
|
||||||
|
// with --incremental-full).
|
||||||
|
extern void
|
||||||
|
gold_fallback(const char* format, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1;
|
||||||
|
|
||||||
// Work around a bug in gcc 4.3.0. http://gcc.gnu.org/PR35546 . This
|
// Work around a bug in gcc 4.3.0. http://gcc.gnu.org/PR35546 . This
|
||||||
// can probably be removed after the bug has been fixed for a while.
|
// can probably be removed after the bug has been fixed for a while.
|
||||||
#ifdef HAVE_TEMPLATE_ATTRIBUTES
|
#ifdef HAVE_TEMPLATE_ATTRIBUTES
|
||||||
|
@ -3125,18 +3125,18 @@ Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
|
|||||||
if (is_debugging_enabled(DEBUG_INCREMENTAL))
|
if (is_debugging_enabled(DEBUG_INCREMENTAL))
|
||||||
this->free_list_.dump();
|
this->free_list_.dump();
|
||||||
gold_assert((*p)->output_section() != NULL);
|
gold_assert((*p)->output_section() != NULL);
|
||||||
gold_fatal(_("out of patch space for section %s; "
|
gold_fallback(_("out of patch space for section %s; "
|
||||||
"relink with --incremental-full"),
|
"relink with --incremental-full"),
|
||||||
(*p)->output_section()->name());
|
(*p)->output_section()->name());
|
||||||
}
|
}
|
||||||
(*p)->set_file_offset(off);
|
(*p)->set_file_offset(off);
|
||||||
(*p)->finalize_data_size();
|
(*p)->finalize_data_size();
|
||||||
if ((*p)->data_size() > current_size)
|
if ((*p)->data_size() > current_size)
|
||||||
{
|
{
|
||||||
gold_assert((*p)->output_section() != NULL);
|
gold_assert((*p)->output_section() != NULL);
|
||||||
gold_fatal(_("%s: section changed size; "
|
gold_fallback(_("%s: section changed size; "
|
||||||
"relink with --incremental-full"),
|
"relink with --incremental-full"),
|
||||||
(*p)->output_section()->name());
|
(*p)->output_section()->name());
|
||||||
}
|
}
|
||||||
gold_debug(DEBUG_INCREMENTAL,
|
gold_debug(DEBUG_INCREMENTAL,
|
||||||
"set_section_offsets: %08lx %08lx %s",
|
"set_section_offsets: %08lx %08lx %s",
|
||||||
@ -3391,8 +3391,8 @@ Layout::create_symtab_sections(const Input_objects* input_objects,
|
|||||||
{
|
{
|
||||||
symtab_off = this->allocate(off, align, *poff);
|
symtab_off = this->allocate(off, align, *poff);
|
||||||
if (off == -1)
|
if (off == -1)
|
||||||
gold_fatal(_("out of patch space for symbol table; "
|
gold_fallback(_("out of patch space for symbol table; "
|
||||||
"relink with --incremental-full"));
|
"relink with --incremental-full"));
|
||||||
gold_debug(DEBUG_INCREMENTAL,
|
gold_debug(DEBUG_INCREMENTAL,
|
||||||
"create_symtab_sections: %08lx %08lx .symtab",
|
"create_symtab_sections: %08lx %08lx .symtab",
|
||||||
static_cast<long>(symtab_off),
|
static_cast<long>(symtab_off),
|
||||||
@ -3462,8 +3462,8 @@ Layout::create_shdrs(const Output_section* shstrtab_section, off_t* poff)
|
|||||||
oshdrs->pre_finalize_data_size();
|
oshdrs->pre_finalize_data_size();
|
||||||
off = this->allocate(oshdrs->data_size(), oshdrs->addralign(), *poff);
|
off = this->allocate(oshdrs->data_size(), oshdrs->addralign(), *poff);
|
||||||
if (off == -1)
|
if (off == -1)
|
||||||
gold_fatal(_("out of patch space for section header table; "
|
gold_fallback(_("out of patch space for section header table; "
|
||||||
"relink with --incremental-full"));
|
"relink with --incremental-full"));
|
||||||
gold_debug(DEBUG_INCREMENTAL,
|
gold_debug(DEBUG_INCREMENTAL,
|
||||||
"create_shdrs: %08lx %08lx (section header table)",
|
"create_shdrs: %08lx %08lx (section header table)",
|
||||||
static_cast<long>(off),
|
static_cast<long>(off),
|
||||||
|
@ -291,6 +291,8 @@ main(int argc, char** argv)
|
|||||||
|
|
||||||
// If the user used --noinhibit-exec, we force the exit status to be
|
// If the user used --noinhibit-exec, we force the exit status to be
|
||||||
// successful. This is compatible with GNU ld.
|
// successful. This is compatible with GNU ld.
|
||||||
gold_exit(errors.error_count() == 0
|
gold_exit((errors.error_count() == 0
|
||||||
|| parameters->options().noinhibit_exec());
|
|| parameters->options().noinhibit_exec())
|
||||||
|
? GOLD_OK
|
||||||
|
: GOLD_ERR);
|
||||||
}
|
}
|
||||||
|
@ -1705,8 +1705,8 @@ Output_data_got<size, big_endian>::add_got_entry(Got_entry got_entry)
|
|||||||
// For an incremental update, find an available slot.
|
// For an incremental update, find an available slot.
|
||||||
off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0);
|
off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0);
|
||||||
if (got_offset == -1)
|
if (got_offset == -1)
|
||||||
gold_fatal(_("out of patch space (GOT);"
|
gold_fallback(_("out of patch space (GOT);"
|
||||||
" relink with --incremental-full"));
|
" relink with --incremental-full"));
|
||||||
unsigned int got_index = got_offset / (size / 8);
|
unsigned int got_index = got_offset / (size / 8);
|
||||||
gold_assert(got_index < this->entries_.size());
|
gold_assert(got_index < this->entries_.size());
|
||||||
this->entries_[got_index] = got_entry;
|
this->entries_[got_index] = got_entry;
|
||||||
@ -1735,8 +1735,8 @@ Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1,
|
|||||||
// For an incremental update, find an available pair of slots.
|
// For an incremental update, find an available pair of slots.
|
||||||
off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0);
|
off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0);
|
||||||
if (got_offset == -1)
|
if (got_offset == -1)
|
||||||
gold_fatal(_("out of patch space (GOT);"
|
gold_fallback(_("out of patch space (GOT);"
|
||||||
" relink with --incremental-full"));
|
" relink with --incremental-full"));
|
||||||
unsigned int got_index = got_offset / (size / 8);
|
unsigned int got_index = got_offset / (size / 8);
|
||||||
gold_assert(got_index < this->entries_.size());
|
gold_assert(got_index < this->entries_.size());
|
||||||
this->entries_[got_index] = got_entry_1;
|
this->entries_[got_index] = got_entry_1;
|
||||||
@ -2270,7 +2270,7 @@ Output_section::add_input_section(Layout* layout,
|
|||||||
offset_in_section = this->free_list_.allocate(input_section_size,
|
offset_in_section = this->free_list_.allocate(input_section_size,
|
||||||
addralign, 0);
|
addralign, 0);
|
||||||
if (offset_in_section == -1)
|
if (offset_in_section == -1)
|
||||||
gold_fatal(_("out of patch space; relink with --incremental-full"));
|
gold_fallback(_("out of patch space; relink with --incremental-full"));
|
||||||
aligned_offset_in_section = offset_in_section;
|
aligned_offset_in_section = offset_in_section;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2374,7 +2374,8 @@ Output_section::add_output_section_data(Output_section_data* posd)
|
|||||||
offset_in_section = this->free_list_.allocate(posd->data_size(),
|
offset_in_section = this->free_list_.allocate(posd->data_size(),
|
||||||
posd->addralign(), 0);
|
posd->addralign(), 0);
|
||||||
if (offset_in_section == -1)
|
if (offset_in_section == -1)
|
||||||
gold_fatal(_("out of patch space; relink with --incremental-full"));
|
gold_fallback(_("out of patch space; "
|
||||||
|
"relink with --incremental-full"));
|
||||||
// Finalize the address and offset now.
|
// Finalize the address and offset now.
|
||||||
uint64_t addr = this->address();
|
uint64_t addr = this->address();
|
||||||
off_t offset = this->offset();
|
off_t offset = this->offset();
|
||||||
@ -4170,17 +4171,17 @@ Output_segment::set_section_list_addresses(Layout* layout, bool reset,
|
|||||||
if (off == -1)
|
if (off == -1)
|
||||||
{
|
{
|
||||||
gold_assert((*p)->output_section() != NULL);
|
gold_assert((*p)->output_section() != NULL);
|
||||||
gold_fatal(_("out of patch space for section %s; "
|
gold_fallback(_("out of patch space for section %s; "
|
||||||
"relink with --incremental-full"),
|
"relink with --incremental-full"),
|
||||||
(*p)->output_section()->name());
|
(*p)->output_section()->name());
|
||||||
}
|
}
|
||||||
(*p)->set_address_and_file_offset(addr + (off - startoff), off);
|
(*p)->set_address_and_file_offset(addr + (off - startoff), off);
|
||||||
if ((*p)->data_size() > current_size)
|
if ((*p)->data_size() > current_size)
|
||||||
{
|
{
|
||||||
gold_assert((*p)->output_section() != NULL);
|
gold_assert((*p)->output_section() != NULL);
|
||||||
gold_fatal(_("%s: section changed size; "
|
gold_fallback(_("%s: section changed size; "
|
||||||
"relink with --incremental-full"),
|
"relink with --incremental-full"),
|
||||||
(*p)->output_section()->name());
|
(*p)->output_section()->name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -915,8 +915,8 @@ Output_data_plt_x86_64::add_entry(Symbol* gsym)
|
|||||||
// For incremental updates, find an available slot.
|
// For incremental updates, find an available slot.
|
||||||
plt_offset = this->free_list_.allocate(plt_entry_size, plt_entry_size, 0);
|
plt_offset = this->free_list_.allocate(plt_entry_size, plt_entry_size, 0);
|
||||||
if (plt_offset == -1)
|
if (plt_offset == -1)
|
||||||
gold_fatal(_("out of patch space (PLT);"
|
gold_fallback(_("out of patch space (PLT);"
|
||||||
" relink with --incremental-full"));
|
" relink with --incremental-full"));
|
||||||
|
|
||||||
// The GOT and PLT entries have a 1-1 correspondance, so the GOT offset
|
// The GOT and PLT entries have a 1-1 correspondance, so the GOT offset
|
||||||
// can be calculated from the PLT index, adjusting for the three
|
// can be calculated from the PLT index, adjusting for the three
|
||||||
|
Loading…
x
Reference in New Issue
Block a user