OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /open8_urisc/trunk/gnu/binutils/gold
    from Rev 27 to Rev 148
    Reverse comparison

Rev 27 → Rev 148

/errors.h
49,6 → 49,12
void
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.
void
error(const char* format, va_list);
/main.cc
291,6 → 291,8
 
// If the user used --noinhibit-exec, we force the exit status to be
// successful. This is compatible with GNU ld.
gold_exit(errors.error_count() == 0
|| parameters->options().noinhibit_exec());
gold_exit((errors.error_count() == 0
|| parameters->options().noinhibit_exec())
? GOLD_OK
: GOLD_ERR);
}
/gold.cc
58,15 → 58,15
Task_token*, Task_token*);
 
void
gold_exit(bool status)
gold_exit(Exit_status status)
{
if (parameters != NULL
&& parameters->options_valid()
&& parameters->options().has_plugins())
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());
exit(status ? EXIT_SUCCESS : EXIT_FAILURE);
exit(status);
}
 
void
87,7 → 87,7
const char* const s = ": out of memory\n";
len = write(2, s, strlen(s));
}
gold_exit(false);
gold_exit(GOLD_ERR);
}
 
// Handle an unreachable case.
97,7 → 97,7
{
fprintf(stderr, _("%s: internal error in %s, at %s:%d\n"),
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
176,7 → 176,7
if (cmdline.begin() == cmdline.end())
{
if (options.printed_version())
gold_exit(true);
gold_exit(GOLD_OK);
gold_fatal(_("no input files"));
}
 
200,6 → 200,9
gold_error(_("incremental linking is incompatible with --icf"));
if (options.has_plugins())
gold_error(_("incremental linking is incompatible with --plugin"));
if (strcmp(options.compress_debug_sections(), "none") != 0)
gold_error(_("incremental linking is incompatible with "
"--compress-debug-sections"));
 
if (parameters->incremental_update())
{
222,7 → 225,7
if (set_parameters_incremental_full())
gold_info(_("linking with --incremental-full"));
else
gold_fatal(_("restart link with --incremental-full"));
gold_fallback(_("restart link with --incremental-full"));
}
}
}
622,11 → 625,13
}
}
 
// For incremental updates, record the existing GOT and PLT entries.
// For incremental updates, record the existing GOT and PLT entries,
// and the COPY relocations.
if (parameters->incremental_update())
{
Incremental_binary* ibase = layout->incremental_base();
ibase->process_got_plt(symtab, layout);
ibase->emit_copy_relocs(symtab);
}
 
if (is_debugging_enabled(DEBUG_SCRIPT))
746,7 → 751,7
// THIS_BLOCKER to be NULL here. There's no real point in
// continuing if that happens.
gold_assert(parameters->errors()->error_count() > 0);
gold_exit(false);
gold_exit(GOLD_ERR);
}
}
 
/common.cc
286,12 → 286,23
gold_unreachable();
}
 
Output_data_space* poc = new Output_data_space(addralign, ds_name);
Output_section* os = layout->add_output_section_data(name,
elfcpp::SHT_NOBITS,
flags, poc,
ORDER_INVALID,
false);
Output_data_space* poc;
Output_section* os;
 
if (!parameters->incremental_update())
{
poc = new Output_data_space(addralign, ds_name);
os = layout->add_output_section_data(name, elfcpp::SHT_NOBITS, flags,
poc, ORDER_INVALID, false);
}
else
{
// When doing an incremental update, we need to allocate each common
// directly from the output section's free list.
poc = NULL;
os = layout->find_output_section(name);
}
 
if (os != NULL)
{
if (commons_section_type == COMMONS_SMALL)
329,12 → 340,26
if (mapfile != NULL)
mapfile->report_allocate_common(sym, ssym->symsize());
 
off = align_address(off, ssym->value());
ssym->allocate_common(poc, off);
off += ssym->symsize();
if (poc != NULL)
{
off = align_address(off, ssym->value());
ssym->allocate_common(poc, off);
off += ssym->symsize();
}
else
{
// For an incremental update, allocate from the free list.
off = os->allocate(ssym->symsize(), ssym->value());
if (off == -1)
gold_fallback(_("out of patch space in section %s; "
"relink with --incremental-full"),
os->name());
ssym->allocate_common(os, off);
}
}
 
poc->set_current_data_size(off);
if (poc != NULL)
poc->set_current_data_size(off);
 
commons->clear();
}
/incremental.cc
22,6 → 22,7
 
#include "gold.h"
 
#include <set>
#include <cstdarg>
#include "libiberty.h"
 
518,11 → 519,45
Sized_incremental_binary<size, big_endian>::do_reserve_layout(
unsigned int input_file_index)
{
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
 
Input_entry_reader input_file =
this->inputs_reader_.input_file(input_file_index);
 
if (input_file.type() == INCREMENTAL_INPUT_SHARED_LIBRARY)
return;
{
// Reserve the BSS space used for COPY relocations.
unsigned int nsyms = input_file.get_global_symbol_count();
Incremental_binary::View symtab_view(NULL);
unsigned int symtab_count;
elfcpp::Elf_strtab strtab(NULL, 0);
this->get_symtab_view(&symtab_view, &symtab_count, &strtab);
for (unsigned int i = 0; i < nsyms; ++i)
{
bool is_def;
bool is_copy;
unsigned int output_symndx =
input_file.get_output_symbol_index(i, &is_def, &is_copy);
if (is_copy)
{
const unsigned char* sym_p = (symtab_view.data()
+ output_symndx * sym_size);
elfcpp::Sym<size, big_endian> gsym(sym_p);
unsigned int shndx = gsym.get_st_shndx();
if (shndx < 1 || shndx >= this->section_map_.size())
continue;
Output_section* os = this->section_map_[shndx];
off_t offset = gsym.get_st_value() - os->address();
os->reserve(offset, gsym.get_st_size());
gold_debug(DEBUG_INCREMENTAL,
"Reserve for COPY reloc: %s, off %d, size %d",
os->name(),
static_cast<int>(offset),
static_cast<int>(gsym.get_st_size()));
}
}
return;
}
 
unsigned int shnum = input_file.get_input_section_count();
for (unsigned int i = 0; i < shnum; i++)
595,10 → 630,14
// FIXME: This should really be a fatal error (corrupt input).
gold_assert(symndx >= first_global && symndx < symtab_count);
Symbol* sym = this->global_symbol(symndx - first_global);
gold_debug(DEBUG_INCREMENTAL,
"GOT entry %d, type %02x: %s",
i, got_type, sym->name());
target->reserve_global_got_entry(i, sym, got_type);
// Add the GOT entry only if the symbol is still referenced.
if (sym != NULL && sym->in_reg())
{
gold_debug(DEBUG_INCREMENTAL,
"GOT entry %d, type %02x: %s",
i, got_type, sym->name());
target->reserve_global_got_entry(i, sym, got_type);
}
}
}
 
609,13 → 648,37
// FIXME: This should really be a fatal error (corrupt input).
gold_assert(plt_desc >= first_global && plt_desc < symtab_count);
Symbol* sym = this->global_symbol(plt_desc - first_global);
gold_debug(DEBUG_INCREMENTAL,
"PLT entry %d: %s",
i, sym->name());
target->register_global_plt_entry(i, sym);
// Add the PLT entry only if the symbol is still referenced.
if (sym->in_reg())
{
gold_debug(DEBUG_INCREMENTAL,
"PLT entry %d: %s",
i, sym->name());
target->register_global_plt_entry(i, sym);
}
}
}
 
// Emit COPY relocations from the existing output file.
 
template<int size, bool big_endian>
void
Sized_incremental_binary<size, big_endian>::do_emit_copy_relocs(
Symbol_table* symtab)
{
Sized_target<size, big_endian>* target =
parameters->sized_target<size, big_endian>();
 
for (typename Copy_relocs::iterator p = this->copy_relocs_.begin();
p != this->copy_relocs_.end();
++p)
{
if (!(*p).symbol->is_copied_from_dynobj())
target->emit_copy_reloc(symtab, (*p).symbol, (*p).output_section,
(*p).offset);
}
}
 
// Apply incremental relocations for symbols whose values have changed.
 
template<int size, bool big_endian>
1493,14 → 1556,24
if (sym->is_forwarder())
sym = this->symtab_->resolve_forwards(sym);
unsigned int shndx = 0;
if (sym->source() == Symbol::FROM_OBJECT
&& sym->object() == obj
&& sym->is_defined())
if (sym->source() != Symbol::FROM_OBJECT)
{
// The symbol was defined by the linker (e.g., common).
// We mark these symbols with a special SHNDX of -1,
// but exclude linker-predefined symbols and symbols
// copied from shared objects.
if (!sym->is_predefined()
&& !sym->is_copied_from_dynobj())
shndx = -1U;
}
else if (sym->object() == obj && sym->is_defined())
{
bool is_ordinary;
unsigned int orig_shndx = sym->shndx(&is_ordinary);
if (is_ordinary)
shndx = index_map[orig_shndx];
else
shndx = 1;
}
unsigned int symtab_index = sym->symtab_index();
unsigned int chain = 0;
1545,7 → 1618,9
== (*p)->get_info_offset());
Incremental_dynobj_entry* entry = (*p)->dynobj_entry();
gold_assert(entry != NULL);
const Object* obj = entry->object();
Object* obj = entry->object();
Dynobj* dynobj = obj->dynobj();
gold_assert(dynobj != NULL);
const Object::Symbols* syms = obj->get_global_symbols();
 
// Write the soname string table index.
1570,12 → 1645,16
sym = this->symtab_->resolve_forwards(sym);
if (sym->symtab_index() == -1U)
continue;
unsigned int def_flag = 0;
unsigned int flags = 0;
if (sym->source() == Symbol::FROM_OBJECT
&& sym->object() == obj
&& sym->is_defined())
def_flag = 1U << 31;
Swap32::writeval(pov, sym->symtab_index() | def_flag);
flags = INCREMENTAL_SHLIB_SYM_DEF;
else if (sym->is_copied_from_dynobj()
&& this->symtab_->get_copy_source(sym) == dynobj)
flags = INCREMENTAL_SHLIB_SYM_COPY;
flags <<= INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
Swap32::writeval(pov, sym->symtab_index() | flags);
pov += 4;
++nsyms_out;
}
1965,7 → 2044,7
st_bind = elfcpp::STB_GLOBAL;
 
unsigned int input_shndx = info.shndx();
if (input_shndx == 0)
if (input_shndx == 0 || input_shndx == -1U)
{
shndx = elfcpp::SHN_UNDEF;
v = 0;
1992,10 → 2071,40
osym.put_st_other(gsym.get_st_other());
osym.put_st_shndx(shndx);
 
this->symbols_[i] =
symtab->add_from_incrobj(this, name, NULL, &sym);
this->ibase_->add_global_symbol(output_symndx - first_global,
this->symbols_[i]);
Symbol* res = symtab->add_from_incrobj(this, name, NULL, &sym);
 
// If this is a linker-defined symbol that hasn't yet been defined,
// define it now.
if (input_shndx == -1U && !res->is_defined())
{
shndx = gsym.get_st_shndx();
v = gsym.get_st_value();
Elf_size_type symsize = gsym.get_st_size();
if (shndx == elfcpp::SHN_ABS)
{
symtab->define_as_constant(name, NULL,
Symbol_table::INCREMENTAL_BASE,
v, symsize, st_type, st_bind,
gsym.get_st_visibility(), 0,
false, false);
}
else
{
Output_section* os = this->ibase_->output_section(shndx);
gold_assert(os != NULL && os->has_fixed_layout());
v -= os->address();
if (symsize > 0)
os->reserve(v, symsize);
symtab->define_in_output_data(name, NULL,
Symbol_table::INCREMENTAL_BASE,
os, v, symsize, st_type, st_bind,
gsym.get_st_visibility(), 0,
false, false);
}
}
 
this->symbols_[i] = res;
this->ibase_->add_global_symbol(output_symndx - first_global, res);
}
}
 
2481,12 → 2590,19
unsigned int isym_count = isymtab.symbol_count();
unsigned int first_global = symtab_count - isym_count;
 
// We keep a set of symbols that we have generated COPY relocations
// for, indexed by the symbol value. We do not need more than one
// COPY relocation per address.
typedef typename std::set<Address> Copied_symbols;
Copied_symbols copied_symbols;
 
const unsigned char* sym_p;
for (unsigned int i = 0; i < nsyms; ++i)
{
bool is_def;
bool is_copy;
unsigned int output_symndx =
this->input_reader_.get_output_symbol_index(i, &is_def);
this->input_reader_.get_output_symbol_index(i, &is_def, &is_copy);
sym_p = symtab_view.data() + output_symndx * sym_size;
elfcpp::Sym<size, big_endian> gsym(sym_p);
const char* name;
2493,7 → 2609,7
if (!strtab.get_c_string(gsym.get_st_name(), &name))
name = "";
 
typename elfcpp::Elf_types<size>::Elf_Addr v;
Address v;
unsigned int shndx;
elfcpp::STB st_bind = gsym.get_st_bind();
elfcpp::STT st_type = gsym.get_st_type();
2523,10 → 2639,24
osym.put_st_other(gsym.get_st_other());
osym.put_st_shndx(shndx);
 
this->symbols_[i] =
symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
Sized_symbol<size>* res =
symtab->add_from_incrobj<size, big_endian>(this, name, NULL, &sym);
this->symbols_[i] = res;
this->ibase_->add_global_symbol(output_symndx - first_global,
this->symbols_[i]);
 
if (is_copy)
{
std::pair<typename Copied_symbols::iterator, bool> ins =
copied_symbols.insert(v);
if (ins.second)
{
unsigned int shndx = gsym.get_st_shndx();
Output_section* os = this->ibase_->output_section(shndx);
off_t offset = v - os->address();
this->ibase_->add_copy_reloc(this->symbols_[i], os, offset);
}
}
}
}
 
/ChangeLog
1,3 → 1,139
2011-06-09 Ian Lance Taylor <iant@google.com>
 
* script-sections.cc
(Orphan_output_section::set_section_addresses): For a relocatable
link set address to 0.
 
2011-06-09 Cary Coutant <ccoutant@google.com>
 
PR gold/12804
* gold/gold.cc (queue_initial_tasks): Warn if --incremental is
used with --compress-debug-sections.
* gold/object.cc (Sized_relobj_file::do_layout): Report
uncompressed size of compressed input sections.
 
2011-06-08 Cary Coutant <ccoutant@google.com>
 
PR gold/12804
* testsuite/two_file_test_2_v1.cc: Change initialization of
v2 to keep it in .data.
 
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>
 
* layout.cc (Layout::set_segment_offsets): Don't adjust layout
for incremental links.
* output.cc (Output_segment::set_section_list_addresses): Remove
FIXME and test for TLS or BSS.
 
2011-06-07 Cary Coutant <ccoutant@google.com>
 
* testsuite/Makefile.am: Add incremental_copy_test,
incremental_common_test_1.
* testsuite/Makefile.in: Regenerate.
* testsuite/common_test_1_v1.c: New source file.
* testsuite/common_test_1_v2.c: New source file.
* testsuite/copy_test_v1.cc: New source file.
 
2011-06-07 Cary Coutant <ccoutant@google.com>
 
* common.cc (Symbol_table::do_allocate_commons_list): For incremental
update, allocate common from bss section's free list.
* incremental-dump.cc (dump_incremental_inputs): Print flag for
linker-defined symbols.
* incremental.cc (Sized_incremental_binary::do_process_got_plt):
Skip GOT and PLT entries that are no longer referenced.
(Output_section_incremental_inputs::write_info_blocks): Mark
linker-defined symbols.
(Sized_incr_relobj::do_add_symbols): Process linker-defined symbols.
* output.cc (Output_section::allocate): New function.
* output.h (Output_section::allocate): New function.
* resolve.cc (Symbol_table::report_resolve_problem): Add case for
linker-defined symbols.
(Symbol::override_base_with_special): Copy is_predefined_ flag.
* symtab.cc (Symbol::init_fields): Initialize is_predefined_ flag.
(Symbol::init_base_output_data): Likewise.
(Symbol::init_base_output_segment): Likewise.
(Symbol::init_base_constant): Likewise.
(Sized_symbol::init_output_data): Likewise.
(Sized_symbol::init_output_segment): Likewise.
(Sized_symbol::init_constant): Likewise.
(Symbol_table::do_define_in_output_data): Likewise.
(Symbol_table::do_define_in_output_segment): Likewise.
(Symbol_table::do_define_as_constant): Likewise.
* symtab.h (Symbol::is_predefined): New function.
(Symbol::init_base_output_data): Add is_predefined parameter.
(Symbol::init_base_output_segment): Likewise.
(Symbol::init_base_constant): Likewise.
(Symbol::is_predefined_): New data member.
(Sized_symbol::init_output_data): Add is_predefined parameter.
(Sized_symbol::init_output_segment): Likewise.
(Sized_symbol::init_constant): Likewise.
(enum Symbol_table::Defined): Add INCREMENTAL_BASE.
 
2011-06-07 Cary Coutant <ccoutant@google.com>
 
* copy-relocs.cc (Copy_relocs::copy_reloc): Call make_copy_reloc
instead of emit_copy_reloc.
(Copy_relocs::emit_copy_reloc): Refactor.
(Copy_relocs::make_copy_reloc): New function.
(Copy_relocs::add_copy_reloc): Remove.
* copy-relocs.h (Copy_relocs::emit_copy_reloc): Move to public
section.
(Copy_relocs::make_copy_reloc): New function.
(Copy_relocs::add_copy_reloc): Remove.
* gold.cc (queue_middle_tasks): Emit old COPY relocations from
unchanged input files.
* incremental-dump.cc (dump_incremental_inputs): Print "COPY" flag.
* incremental.cc (Sized_incremental_binary::do_reserve_layout):
Reserve BSS space for COPY relocations.
(Sized_incremental_binary::do_emit_copy_relocs): New function.
(Output_section_incremental_inputs::write_info_blocks): Record
whether a symbol is copied from a shared object.
(Sized_incr_dynobj::do_add_symbols): Record COPY relocations.
* incremental.h (enum Incremental_shlib_symbol_flags): New type.
(INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT): New constant.
(Incremental_input_entry_reader::get_output_symbol_index): Add
is_copy parameter.
(Incremental_binary::emit_copy_relocs): New function.
(Incremental_binary::do_emit_copy_relocs): New function.
(Sized_incremental_binary::Sized_incremental_binary): Initialize
new data member.
(Sized_incremental_binary::add_copy_reloc): New function.
(Sized_incremental_binary::do_emit_copy_relocs): New function.
(Sized_incremental_binary::Copy_reloc): New struct.
(Sized_incremental_binary::Copy_relocs): New typedef.
(Sized_incremental_binary::copy_relocs_): New data member.
* symtab.cc (Symbol_table::add_from_incrobj): Change return type.
* symtab.h (Symbol_table::add_from_incrobj): Change return type.
* target.h (Sized_target::emit_copy_reloc): New function.
* x86_64.cc (Target_x86_64::emit_copy_reloc): New function.
 
2011-06-02 Cary Coutant <ccoutant@google.com>
 
PR gold/12163
/testsuite/copy_test_v1.cc
0,0 → 1,47
// copy_test_v1.cc -- test copy relocs for gold
 
// Copyright 2008, 2011 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
 
// This file is part of gold.
 
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
// MA 02110-1301, USA.
 
// This source file is used for testing the --incremental option.
// The object built from this source will be incrementally updated
// with the correct object built from copy_test.cc.
 
#include <cassert>
#include <stdint.h>
 
// Misalign the BSS section.
static char c;
 
// From copy_test_1.cc.
extern char b;
 
// From copy_test_2.cc.
extern long long l;
 
int
main()
{
assert(c == 0);
assert(b == 1);
assert(l == 3); // Deliberately incorrect.
assert((reinterpret_cast<uintptr_t>(&l) & 0x7) == 0);
return 0;
}
/testsuite/Makefile.am
1851,6 → 1851,22
cp -f two_file_test_2.o two_file_test_tmp_4.o
$(CXXLINK) -Wl,--incremental-update,--incremental-base=incremental_test_4.base -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp_4.o two_file_test_main.o
 
check_PROGRAMS += incremental_copy_test
incremental_copy_test: copy_test_v1.o copy_test.o copy_test_1.so copy_test_2.so
cp -f copy_test_v1.o copy_test_tmp.o
$(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ -Wl,-R,. copy_test_tmp.o copy_test_1.so copy_test_2.so
@sleep 1
cp -f copy_test.o copy_test_tmp.o
$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ -Wl,-R,. copy_test_tmp.o copy_test_1.so copy_test_2.so
 
check_PROGRAMS += incremental_common_test_1
incremental_common_test_1: common_test_1_v1.o common_test_1_v2.o gcctestdir/ld
cp -f common_test_1_v1.o common_test_1_tmp.o
$(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ common_test_1_tmp.o
@sleep 1
cp -f common_test_1_v2.o common_test_1_tmp.o
$(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ common_test_1_tmp.o
 
endif DEFAULT_TARGET_X86_64
 
endif GCC
/testsuite/common_test_1_v1.c
0,0 → 1,79
/* common_test_1_v1.c -- test common symbol sorting
 
Copyright 2008, 2011 Free Software Foundation, Inc.
Written by Ian Lance Taylor <iant@google.com>
 
This file is part of gold.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA.
 
This is a test of a common symbol in the main program and a
versioned symbol in a shared library. The common symbol in the
main program should override the shared library symbol.
 
This file is a modified version of the real test case, to be used
while testing the --incremental option. */
 
#include <assert.h>
 
/* Common symbols should be sorted by size, largest first, and then by
alignment, largest first. We mix up the names, because gas seems
to sort common symbols roughly by name. */
 
int c9[90];
int c8[80];
int c7[70];
int c6[60];
int c5[10];
int c4[20];
int c3[30];
int c2[40];
int c1[50];
 
int a1 __attribute__ ((aligned (1 << 9)));
int a2 __attribute__ ((aligned (1 << 8)));
int a3 __attribute__ ((aligned (1 << 7)));
int a4 __attribute__ ((aligned (1 << 6)));
int a5 __attribute__ ((aligned (1 << 1)));
int a6 __attribute__ ((aligned (1 << 2)));
int a7 __attribute__ ((aligned (1 << 3)));
int a8 __attribute__ ((aligned (1 << 4)));
int a9 __attribute__ ((aligned (1 << 5)));
 
int
main (int argc __attribute__ ((unused)), char** argv __attribute__ ((unused)))
{
/* These tests are deliberately incorrect. */
assert (c5 < c4);
assert (c4 < c3);
assert (c3 < c2);
assert (c2 < c1);
assert (c1 < c6);
assert (c6 < c7);
assert (c7 < c8);
assert (c8 < c9);
 
assert (&a1 > &a2);
assert (&a2 > &a3);
assert (&a3 > &a4);
assert (&a4 > &a9);
assert (&a9 > &a8);
assert (&a8 > &a7);
assert (&a7 > &a6);
assert (&a6 > &a5);
 
return 0;
}
/testsuite/two_file_test_2_v1.cc
46,7 → 46,7
 
// 2 Code in file 1 refers to global data in file 2.
 
int v2 = 0;
int v2 = 1;
 
// 3 Code in file 1 referes to common symbol in file 2. This is
// initialized at runtime to 789.
/testsuite/common_test_1_v2.c
0,0 → 1,77
/* common_test_1_v2.c -- test common symbol sorting
 
Copyright 2008 Free Software Foundation, Inc.
Written by Ian Lance Taylor <iant@google.com>
 
This file is part of gold.
 
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
 
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA.
 
This is a test of a common symbol in the main program and a
versioned symbol in a shared library. The common symbol in the
main program should override the shared library symbol. */
 
#include <assert.h>
 
/* Common symbols should be sorted by size, largest first, and then by
alignment, largest first. We mix up the names, because gas seems
to sort common symbols roughly by name. */
 
int c9[90];
int c8[80];
int c7[70];
int c6[60];
int c5[10];
int c4[20];
int c3[30];
int c2[40];
int c1[50];
 
int a1 __attribute__ ((aligned (1 << 9)));
int a2 __attribute__ ((aligned (1 << 8)));
int a3 __attribute__ ((aligned (1 << 7)));
int a4 __attribute__ ((aligned (1 << 6)));
int a5 __attribute__ ((aligned (1 << 1)));
int a6 __attribute__ ((aligned (1 << 2)));
int a7 __attribute__ ((aligned (1 << 3)));
int a8 __attribute__ ((aligned (1 << 4)));
int a9 __attribute__ ((aligned (1 << 5)));
 
int
main (int argc __attribute__ ((unused)), char** argv __attribute__ ((unused)))
{
// After an incremental update, all guarantees about ordering
// are null.
assert (c5 != c4);
assert (c4 != c3);
assert (c3 != c2);
assert (c2 != c1);
assert (c1 != c6);
assert (c6 != c7);
assert (c7 != c8);
assert (c8 != c9);
 
assert (&a1 != &a2);
assert (&a2 != &a3);
assert (&a3 != &a4);
assert (&a4 != &a9);
assert (&a9 != &a8);
assert (&a8 != &a7);
assert (&a7 != &a6);
assert (&a6 != &a5);
 
return 0;
}
/testsuite/Makefile.in
435,7 → 435,9
# Incremental linking is currently supported only on the x86_64 target.
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_35 = incremental_test_2 \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_3 \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4 \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_copy_test \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_common_test_1
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__append_36 = two_file_test_tmp_2.o \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_test_tmp_3.o \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4.base \
683,7 → 685,9
@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_22 = start_lib_test$(EXEEXT)
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am__EXEEXT_23 = incremental_test_2$(EXEEXT) \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_3$(EXEEXT) \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4$(EXEEXT)
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_test_4$(EXEEXT) \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_copy_test$(EXEEXT) \
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ incremental_common_test_1$(EXEEXT)
basic_pic_test_SOURCES = basic_pic_test.c
basic_pic_test_OBJECTS = basic_pic_test.$(OBJEXT)
basic_pic_test_LDADD = $(LDADD)
1008,6 → 1012,19
ifuncmain7static_OBJECTS = $(am_ifuncmain7static_OBJECTS)
ifuncmain7static_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(ifuncmain7static_LDFLAGS) $(LDFLAGS) -o $@
incremental_common_test_1_SOURCES = incremental_common_test_1.c
incremental_common_test_1_OBJECTS = \
incremental_common_test_1.$(OBJEXT)
incremental_common_test_1_LDADD = $(LDADD)
incremental_common_test_1_DEPENDENCIES = libgoldtest.a ../libgold.a \
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
incremental_copy_test_SOURCES = incremental_copy_test.c
incremental_copy_test_OBJECTS = incremental_copy_test.$(OBJEXT)
incremental_copy_test_LDADD = $(LDADD)
incremental_copy_test_DEPENDENCIES = libgoldtest.a ../libgold.a \
../../libiberty/libiberty.a $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
incremental_test_2_SOURCES = incremental_test_2.c
incremental_test_2_OBJECTS = incremental_test_2.$(OBJEXT)
incremental_test_2_LDADD = $(LDADD)
1504,7 → 1521,8
$(ifuncmain5static_SOURCES) ifuncmain5staticpic.c \
ifuncmain6pie.c $(ifuncmain7_SOURCES) ifuncmain7pic.c \
ifuncmain7picstatic.c ifuncmain7pie.c \
$(ifuncmain7static_SOURCES) incremental_test_2.c \
$(ifuncmain7static_SOURCES) incremental_common_test_1.c \
incremental_copy_test.c incremental_test_2.c \
incremental_test_3.c incremental_test_4.c $(initpri1_SOURCES) \
$(justsyms_SOURCES) $(large_SOURCES) local_labels_test.c \
many_sections_r_test.c $(many_sections_test_SOURCES) \
2577,6 → 2595,24
ifuncmain7static$(EXEEXT): $(ifuncmain7static_OBJECTS) $(ifuncmain7static_DEPENDENCIES)
@rm -f ifuncmain7static$(EXEEXT)
$(ifuncmain7static_LINK) $(ifuncmain7static_OBJECTS) $(ifuncmain7static_LDADD) $(LIBS)
@DEFAULT_TARGET_X86_64_FALSE@incremental_common_test_1$(EXEEXT): $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_DEPENDENCIES)
@DEFAULT_TARGET_X86_64_FALSE@ @rm -f incremental_common_test_1$(EXEEXT)
@DEFAULT_TARGET_X86_64_FALSE@ $(LINK) $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_LDADD) $(LIBS)
@GCC_FALSE@incremental_common_test_1$(EXEEXT): $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_DEPENDENCIES)
@GCC_FALSE@ @rm -f incremental_common_test_1$(EXEEXT)
@GCC_FALSE@ $(LINK) $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_LDADD) $(LIBS)
@NATIVE_LINKER_FALSE@incremental_common_test_1$(EXEEXT): $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_DEPENDENCIES)
@NATIVE_LINKER_FALSE@ @rm -f incremental_common_test_1$(EXEEXT)
@NATIVE_LINKER_FALSE@ $(LINK) $(incremental_common_test_1_OBJECTS) $(incremental_common_test_1_LDADD) $(LIBS)
@DEFAULT_TARGET_X86_64_FALSE@incremental_copy_test$(EXEEXT): $(incremental_copy_test_OBJECTS) $(incremental_copy_test_DEPENDENCIES)
@DEFAULT_TARGET_X86_64_FALSE@ @rm -f incremental_copy_test$(EXEEXT)
@DEFAULT_TARGET_X86_64_FALSE@ $(LINK) $(incremental_copy_test_OBJECTS) $(incremental_copy_test_LDADD) $(LIBS)
@GCC_FALSE@incremental_copy_test$(EXEEXT): $(incremental_copy_test_OBJECTS) $(incremental_copy_test_DEPENDENCIES)
@GCC_FALSE@ @rm -f incremental_copy_test$(EXEEXT)
@GCC_FALSE@ $(LINK) $(incremental_copy_test_OBJECTS) $(incremental_copy_test_LDADD) $(LIBS)
@NATIVE_LINKER_FALSE@incremental_copy_test$(EXEEXT): $(incremental_copy_test_OBJECTS) $(incremental_copy_test_DEPENDENCIES)
@NATIVE_LINKER_FALSE@ @rm -f incremental_copy_test$(EXEEXT)
@NATIVE_LINKER_FALSE@ $(LINK) $(incremental_copy_test_OBJECTS) $(incremental_copy_test_LDADD) $(LIBS)
@DEFAULT_TARGET_X86_64_FALSE@incremental_test_2$(EXEEXT): $(incremental_test_2_OBJECTS) $(incremental_test_2_DEPENDENCIES)
@DEFAULT_TARGET_X86_64_FALSE@ @rm -f incremental_test_2$(EXEEXT)
@DEFAULT_TARGET_X86_64_FALSE@ $(LINK) $(incremental_test_2_OBJECTS) $(incremental_test_2_LDADD) $(LIBS)
2971,6 → 3007,8
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifuncmain7pic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifuncmain7picstatic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ifuncmain7pie.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental_common_test_1.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental_copy_test.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental_test_2.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental_test_3.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/incremental_test_4.Po@am__quote@
3652,6 → 3690,10
@p='incremental_test_3$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
incremental_test_4.log: incremental_test_4$(EXEEXT)
@p='incremental_test_4$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
incremental_copy_test.log: incremental_copy_test$(EXEEXT)
@p='incremental_copy_test$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
incremental_common_test_1.log: incremental_common_test_1$(EXEEXT)
@p='incremental_common_test_1$(EXEEXT)'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post)
.test.log:
@p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post)
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
4615,6 → 4657,18
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @sleep 1
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f two_file_test_2.o two_file_test_tmp_4.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-update,--incremental-base=incremental_test_4.base -Bgcctestdir/ two_file_test_1.o two_file_test_1b.o two_file_test_tmp_4.o two_file_test_main.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@incremental_copy_test: copy_test_v1.o copy_test.o copy_test_1.so copy_test_2.so
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f copy_test_v1.o copy_test_tmp.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ -Wl,-R,. copy_test_tmp.o copy_test_1.so copy_test_2.so
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @sleep 1
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f copy_test.o copy_test_tmp.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ -Wl,-R,. copy_test_tmp.o copy_test_1.so copy_test_2.so
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@incremental_common_test_1: common_test_1_v1.o common_test_1_v2.o gcctestdir/ld
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f common_test_1_v1.o common_test_1_tmp.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-full -Bgcctestdir/ common_test_1_tmp.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ @sleep 1
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ cp -f common_test_1_v2.o common_test_1_tmp.o
@DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ $(CXXLINK) -Wl,--incremental-update -Bgcctestdir/ common_test_1_tmp.o
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10.o: script_test_10.s
@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $<
@NATIVE_OR_CROSS_LINKER_TRUE@script_test_10: $(srcdir)/script_test_10.t script_test_10.o gcctestdir/ld
/object.cc
1299,8 → 1299,13
&& (shdr.get_sh_type() == elfcpp::SHT_PROGBITS
|| shdr.get_sh_type() == elfcpp::SHT_NOBITS
|| shdr.get_sh_type() == elfcpp::SHT_NOTE))
incremental_inputs->report_input_section(this, i, name,
shdr.get_sh_size());
{
off_t sh_size = shdr.get_sh_size();
section_size_type uncompressed_size;
if (this->section_is_compressed(i, &uncompressed_size))
sh_size = uncompressed_size;
incremental_inputs->report_input_section(this, i, name, sh_size);
}
 
if (discard)
{
/errors.cc
81,9 → 81,20
fprintf(stderr, _("%s: fatal error: "), this->program_name_);
vfprintf(stderr, format, args);
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.
 
void
212,6 → 223,17
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.
 
void
/target.h
833,6 → 833,13
Symbol*)
{ gold_unreachable(); }
 
// Force a COPY relocation for a given symbol.
// A target needs to implement this to support incremental linking.
 
virtual void
emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t)
{ gold_unreachable(); }
 
// Apply an incremental relocation.
 
virtual void
/symtab.cc
79,6 → 79,7
this->is_defined_in_discarded_section_ = false;
this->undef_binding_set_ = false;
this->undef_binding_weak_ = false;
this->is_predefined_ = false;
}
 
// Return the demangled version of the symbol's name, but only
133,7 → 134,8
Symbol::init_base_output_data(const char* name, const char* version,
Output_data* od, elfcpp::STT type,
elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis, bool offset_is_from_end)
unsigned char nonvis, bool offset_is_from_end,
bool is_predefined)
{
this->init_fields(name, version, type, binding, visibility, nonvis);
this->u_.in_output_data.output_data = od;
141,6 → 143,7
this->source_ = IN_OUTPUT_DATA;
this->in_reg_ = true;
this->in_real_elf_ = true;
this->is_predefined_ = is_predefined;
}
 
// Initialize the fields in the base class Symbol for a symbol defined
151,7 → 154,8
Output_segment* os, elfcpp::STT type,
elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis,
Segment_offset_base offset_base)
Segment_offset_base offset_base,
bool is_predefined)
{
this->init_fields(name, version, type, binding, visibility, nonvis);
this->u_.in_output_segment.output_segment = os;
159,6 → 163,7
this->source_ = IN_OUTPUT_SEGMENT;
this->in_reg_ = true;
this->in_real_elf_ = true;
this->is_predefined_ = is_predefined;
}
 
// Initialize the fields in the base class Symbol for a symbol defined
167,12 → 172,14
void
Symbol::init_base_constant(const char* name, const char* version,
elfcpp::STT type, elfcpp::STB binding,
elfcpp::STV visibility, unsigned char nonvis)
elfcpp::STV visibility, unsigned char nonvis,
bool is_predefined)
{
this->init_fields(name, version, type, binding, visibility, nonvis);
this->source_ = IS_CONSTANT;
this->in_reg_ = true;
this->in_real_elf_ = true;
this->is_predefined_ = is_predefined;
}
 
// Initialize the fields in the base class Symbol for an undefined
227,10 → 234,11
elfcpp::STB binding,
elfcpp::STV visibility,
unsigned char nonvis,
bool offset_is_from_end)
bool offset_is_from_end,
bool is_predefined)
{
this->init_base_output_data(name, version, od, type, binding, visibility,
nonvis, offset_is_from_end);
nonvis, offset_is_from_end, is_predefined);
this->value_ = value;
this->symsize_ = symsize;
}
246,10 → 254,11
elfcpp::STB binding,
elfcpp::STV visibility,
unsigned char nonvis,
Segment_offset_base offset_base)
Segment_offset_base offset_base,
bool is_predefined)
{
this->init_base_output_segment(name, version, os, type, binding, visibility,
nonvis, offset_base);
nonvis, offset_base, is_predefined);
this->value_ = value;
this->symsize_ = symsize;
}
262,9 → 271,11
Sized_symbol<size>::init_constant(const char* name, const char* version,
Value_type value, Size_type symsize,
elfcpp::STT type, elfcpp::STB binding,
elfcpp::STV visibility, unsigned char nonvis)
elfcpp::STV visibility, unsigned char nonvis,
bool is_predefined)
{
this->init_base_constant(name, version, type, binding, visibility, nonvis);
this->init_base_constant(name, version, type, binding, visibility, nonvis,
is_predefined);
this->value_ = value;
this->symsize_ = symsize;
}
1489,7 → 1500,7
// Add a symbol from a incremental object file.
 
template<int size, bool big_endian>
Symbol*
Sized_symbol<size>*
Symbol_table::add_from_incrobj(
Object* obj,
const char* name,
1843,7 → 1854,8
return NULL;
 
sym->init_output_data(name, version, od, value, symsize, type, binding,
visibility, nonvis, offset_is_from_end);
visibility, nonvis, offset_is_from_end,
defined == PREDEFINED);
 
if (oldsym == NULL)
{
1956,7 → 1968,8
return NULL;
 
sym->init_output_segment(name, version, os, value, symsize, type, binding,
visibility, nonvis, offset_base);
visibility, nonvis, offset_base,
defined == PREDEFINED);
 
if (oldsym == NULL)
{
2068,7 → 2081,7
return NULL;
 
sym->init_constant(name, version, value, symsize, type, binding, visibility,
nonvis);
nonvis, defined == PREDEFINED);
 
if (oldsym == NULL)
{
3453,7 → 3466,7
 
#ifdef HAVE_TARGET_32_LITTLE
template
Symbol*
Sized_symbol<32>*
Symbol_table::add_from_incrobj(
Object* obj,
const char* name,
3463,7 → 3476,7
 
#ifdef HAVE_TARGET_32_BIG
template
Symbol*
Sized_symbol<32>*
Symbol_table::add_from_incrobj(
Object* obj,
const char* name,
3473,7 → 3486,7
 
#ifdef HAVE_TARGET_64_LITTLE
template
Symbol*
Sized_symbol<64>*
Symbol_table::add_from_incrobj(
Object* obj,
const char* name,
3483,7 → 3496,7
 
#ifdef HAVE_TARGET_64_BIG
template
Symbol*
Sized_symbol<64>*
Symbol_table::add_from_incrobj(
Object* obj,
const char* name,
/symtab.h
803,6 → 803,11
&& !this->is_func());
}
 
// Return true if this symbol was predefined by the linker.
bool
is_predefined() const
{ return this->is_predefined_; }
 
protected:
// Instances of this class should always be created at a specific
// size.
828,7 → 833,8
void
init_base_output_data(const char* name, const char* version, Output_data*,
elfcpp::STT, elfcpp::STB, elfcpp::STV,
unsigned char nonvis, bool offset_is_from_end);
unsigned char nonvis, bool offset_is_from_end,
bool is_predefined);
 
// Initialize fields for an Output_segment.
void
836,13 → 842,14
Output_segment* os, elfcpp::STT type,
elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis,
Segment_offset_base offset_base);
Segment_offset_base offset_base,
bool is_predefined);
 
// Initialize fields for a constant.
void
init_base_constant(const char* name, const char* version, elfcpp::STT type,
elfcpp::STB binding, elfcpp::STV visibility,
unsigned char nonvis);
unsigned char nonvis, bool is_predefined);
 
// Initialize fields for an undefined symbol.
void
991,6 → 998,8
// True if this symbol was a weak undef resolved by a dynamic def
// (bit 33).
bool undef_binding_weak_ : 1;
// True if this symbol is a predefined linker symbol (bit 34).
bool is_predefined_ : 1;
};
 
// The parts of a symbol which are size specific. Using a template
1020,7 → 1029,7
init_output_data(const char* name, const char* version, Output_data*,
Value_type value, Size_type symsize, elfcpp::STT,
elfcpp::STB, elfcpp::STV, unsigned char nonvis,
bool offset_is_from_end);
bool offset_is_from_end, bool is_predefined);
 
// Initialize fields for an Output_segment.
void
1027,13 → 1036,13
init_output_segment(const char* name, const char* version, Output_segment*,
Value_type value, Size_type symsize, elfcpp::STT,
elfcpp::STB, elfcpp::STV, unsigned char nonvis,
Segment_offset_base offset_base);
Segment_offset_base offset_base, bool is_predefined);
 
// Initialize fields for a constant.
void
init_constant(const char* name, const char* version, Value_type value,
Size_type symsize, elfcpp::STT, elfcpp::STB, elfcpp::STV,
unsigned char nonvis);
unsigned char nonvis, bool is_predefined);
 
// Initialize fields for an undefined symbol.
void
1250,6 → 1259,9
SCRIPT,
// Predefined by the linker.
PREDEFINED,
// Defined by the linker during an incremental base link, but not
// a predefined symbol (e.g., common, defined in script).
INCREMENTAL_BASE,
};
 
// The order in which we sort common symbols.
1341,7 → 1353,7
// Add one external symbol from the incremental object OBJ to the symbol
// table. Returns a pointer to the resolved symbol in the symbol table.
template<int size, bool big_endian>
Symbol*
Sized_symbol<size>*
add_from_incrobj(Object* obj, const char* name,
const char* ver, elfcpp::Sym<size, big_endian>* sym);
 
/output.h
3432,6 → 3432,11
void
reserve(uint64_t sh_offset, uint64_t sh_size);
 
// Allocate space from the free list for the section. Used for
// incremental update links.
off_t
allocate(off_t len, uint64_t addralign);
 
protected:
// Return the output section--i.e., the object itself.
Output_section*
/incremental-dump.cc
293,8 → 293,9
for (unsigned int symndx = 0; symndx < nsyms; ++symndx)
{
bool is_def;
bool is_copy;
unsigned int output_symndx =
input_file.get_output_symbol_index(symndx, &is_def);
input_file.get_output_symbol_index(symndx, &is_def, &is_copy);
sym_p = symtab_view.data() + output_symndx * sym_size;
elfcpp::Sym<size, big_endian> sym(sym_p);
const char* symname;
303,7 → 304,7
printf(" %6d %6s %8s %8s %8s %8s %-5s %s\n",
output_symndx,
"", "", "", "", "",
is_def ? "DEF" : "UNDEF",
is_copy ? "COPY" : (is_def ? "DEF" : "UNDEF"),
symname);
}
}
321,12 → 322,14
symname = "<unknown>";
printf(" %6d %6d %8d %8d %8d %8d %-5s %s\n",
output_symndx,
info.shndx(),
info.shndx() == -1U ? -1 : info.shndx(),
input_file.get_symbol_offset(symndx),
info.next_offset(),
info.reloc_count(),
info.reloc_offset(),
info.shndx() != elfcpp::SHN_UNDEF ? "DEF" : "UNDEF",
(info.shndx() == -1U
? "BASE"
: info.shndx() == 0 ? "UNDEF" : "DEF"),
symname);
}
}
/resolve.cc
830,6 → 830,7
objname = _("linker script");
break;
case PREDEFINED:
case INCREMENTAL_BASE:
objname = _("linker defined");
break;
default:
908,6 → 909,8
if (from->needs_dynsym_value_)
this->needs_dynsym_value_ = true;
 
this->is_predefined_ = from->is_predefined_;
 
// We shouldn't see these flags. If we do, we need to handle them
// somehow.
gold_assert(!from->is_forwarder_);
/gold.h
27,6 → 27,7
#include "ansidecl.h"
 
#include <cstddef>
#include <cstdlib>
#include <cstring>
#include <stdint.h>
#include <sys/types.h>
166,6 → 167,15
template<int size, bool big_endian>
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.
 
// For an offset in an input or output file, use off_t. Note that
183,7 → 193,7
// This function is called to exit the program. Status is true to
// exit success (0) and false to exit failure (1).
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
// immediately exit with failure.
203,6 → 213,13
extern void
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
// can probably be removed after the bug has been fixed for a while.
#ifdef HAVE_TEMPLATE_ATTRIBUTES
/script-sections.cc
2846,6 → 2846,17
uint64_t address = *dot_value;
address = align_address(address, this->os_->addralign());
 
// For a relocatable link, all orphan sections are put at
// address 0. In general we expect all sections to be at
// address 0 for a relocatable link, but we permit the linker
// script to override that for specific output sections.
if (parameters->options().relocatable())
{
address = 0;
*load_address = 0;
have_load_address = false;
}
 
if ((this->os_->flags() & elfcpp::SHF_ALLOC) != 0)
{
this->os_->set_address(address);
/x86_64.cc
405,10 → 405,13
unsigned int got_type);
 
// Register an existing PLT entry for a global symbol.
// A target needs to implement this to support incremental linking.
void
register_global_plt_entry(unsigned int plt_index, Symbol* gsym);
 
// Force a COPY relocation for a given symbol.
void
emit_copy_reloc(Symbol_table*, Symbol*, Output_section*, off_t);
 
// Apply an incremental relocation.
void
apply_relocation(const Relocate_info<64, false>* relinfo,
912,8 → 915,8
// For incremental updates, find an available slot.
plt_offset = this->free_list_.allocate(plt_entry_size, plt_entry_size, 0);
if (plt_offset == -1)
gold_fatal(_("out of patch space (PLT);"
" relink with --incremental-full"));
gold_fallback(_("out of patch space (PLT);"
" relink with --incremental-full"));
 
// 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
1389,6 → 1392,19
this->plt_->add_relocation(gsym, got_offset);
}
 
// Force a COPY relocation for a given symbol.
 
void
Target_x86_64::emit_copy_reloc(
Symbol_table* symtab, Symbol* sym, Output_section* os, off_t offset)
{
this->copy_relocs_.emit_copy_reloc(symtab,
symtab->get_sized_symbol<64>(sym),
os,
offset,
this->rela_dyn_section(NULL));
}
 
// Define the _TLS_MODULE_BASE_ symbol in the TLS segment.
 
void
/copy-relocs.cc
65,7 → 65,7
Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
{
if (this->need_copy_reloc(sym, object, shndx))
this->emit_copy_reloc(symtab, layout, sym, reloc_section);
this->make_copy_reloc(symtab, layout, sym, reloc_section);
else
{
// We may not need a COPY relocation. Save this relocation to
106,6 → 106,24
void
Copy_relocs<sh_type, size, big_endian>::emit_copy_reloc(
Symbol_table* symtab,
Sized_symbol<size>* sym,
Output_data* posd,
off_t offset,
Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
{
// Define the symbol as being copied.
symtab->define_with_copy_reloc(sym, posd, offset);
 
// Add the COPY relocation to the dynamic reloc section.
reloc_section->add_global(sym, this->copy_reloc_type_, posd, offset, 0);
}
 
// Make a COPY relocation for SYM and emit it.
 
template<int sh_type, int size, bool big_endian>
void
Copy_relocs<sh_type, size, big_endian>::make_copy_reloc(
Symbol_table* symtab,
Layout* layout,
Sized_symbol<size>* sym,
Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
164,26 → 182,9
section_size_type offset = dynbss_size;
dynbss->set_current_data_size(dynbss_size + symsize);
 
// Define the symbol as being copied.
symtab->define_with_copy_reloc(sym, dynbss, offset);
 
// Add the COPY relocation to the dynamic reloc section.
this->add_copy_reloc(sym, offset, reloc_section);
this->emit_copy_reloc(symtab, sym, dynbss, offset, reloc_section);
}
 
// Add a COPY relocation for SYM to RELOC_SECTION.
 
template<int sh_type, int size, bool big_endian>
void
Copy_relocs<sh_type, size, big_endian>::add_copy_reloc(
Symbol* sym,
section_size_type offset,
Output_data_reloc<sh_type, true, size, big_endian>* reloc_section)
{
reloc_section->add_global(sym, this->copy_reloc_type_, this->dynbss_,
offset, 0);
}
 
// Save a relocation to possibly be emitted later.
 
template<int sh_type, int size, bool big_endian>
/output.cc
1705,8 → 1705,8
// For an incremental update, find an available slot.
off_t got_offset = this->free_list_.allocate(size / 8, size / 8, 0);
if (got_offset == -1)
gold_fatal(_("out of patch space (GOT);"
" relink with --incremental-full"));
gold_fallback(_("out of patch space (GOT);"
" relink with --incremental-full"));
unsigned int got_index = got_offset / (size / 8);
gold_assert(got_index < this->entries_.size());
this->entries_[got_index] = got_entry;
1735,8 → 1735,8
// For an incremental update, find an available pair of slots.
off_t got_offset = this->free_list_.allocate(2 * size / 8, size / 8, 0);
if (got_offset == -1)
gold_fatal(_("out of patch space (GOT);"
" relink with --incremental-full"));
gold_fallback(_("out of patch space (GOT);"
" relink with --incremental-full"));
unsigned int got_index = got_offset / (size / 8);
gold_assert(got_index < this->entries_.size());
this->entries_[got_index] = got_entry_1;
2270,7 → 2270,7
offset_in_section = this->free_list_.allocate(input_section_size,
addralign, 0);
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;
}
else
2374,7 → 2374,8
offset_in_section = this->free_list_.allocate(posd->data_size(),
posd->addralign(), 0);
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.
uint64_t addr = this->address();
off_t offset = this->offset();
3726,6 → 3727,7
 
// Reserve space within the fixed layout for the section. Used for
// incremental update links.
 
void
Output_section::reserve(uint64_t sh_offset, uint64_t sh_size)
{
3732,6 → 3734,15
this->free_list_.remove(sh_offset, sh_offset + sh_size);
}
 
// Allocate space from the free list for the section. Used for
// incremental update links.
 
off_t
Output_section::allocate(off_t len, uint64_t addralign)
{
return this->free_list_.allocate(len, addralign, 0);
}
 
// Output segment methods.
 
Output_segment::Output_segment(elfcpp::Elf_Word type, elfcpp::Elf_Word flags)
4146,10 → 4157,7
}
}
 
// FIXME: Need to handle TLS and .bss with incremental update.
if (!parameters->incremental_update()
|| (*p)->is_section_flag_set(elfcpp::SHF_TLS)
|| (*p)->is_section_type(elfcpp::SHT_NOBITS))
if (!parameters->incremental_update())
{
off = align_address(off, align);
(*p)->set_address_and_file_offset(addr + (off - startoff), off);
4163,17 → 4171,17
if (off == -1)
{
gold_assert((*p)->output_section() != NULL);
gold_fatal(_("out of patch space for section %s; "
"relink with --incremental-full"),
(*p)->output_section()->name());
gold_fallback(_("out of patch space for section %s; "
"relink with --incremental-full"),
(*p)->output_section()->name());
}
(*p)->set_address_and_file_offset(addr + (off - startoff), off);
if ((*p)->data_size() > current_size)
{
gold_assert((*p)->output_section() != NULL);
gold_fatal(_("%s: section changed size; "
"relink with --incremental-full"),
(*p)->output_section()->name());
gold_fallback(_("%s: section changed size; "
"relink with --incremental-full"),
(*p)->output_section()->name());
}
}
}
/copy-relocs.h
81,6 → 81,12
void
emit(Output_data_reloc<sh_type, true, size, big_endian>*);
 
// Emit a COPY reloc.
void
emit_copy_reloc(Symbol_table*, Sized_symbol<size>*,
Output_data*, off_t,
Output_data_reloc<sh_type, true, size, big_endian>*);
 
private:
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
126,16 → 132,11
Sized_relobj_file<size, big_endian>* object,
unsigned int shndx) const;
 
// Emit a COPY reloc.
// Make a new COPY reloc and emit it.
void
emit_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
make_copy_reloc(Symbol_table*, Layout*, Sized_symbol<size>*,
Output_data_reloc<sh_type, true, size, big_endian>*);
 
// Add a COPY reloc to the dynamic reloc section.
void
add_copy_reloc(Symbol*, section_size_type,
Output_data_reloc<sh_type, true, size, big_endian>*);
 
// Save a reloc against SYM for possible emission later.
void
save(Symbol*, Sized_relobj_file<size, big_endian>*, unsigned int shndx,
/incremental.h
68,6 → 68,20
INCREMENTAL_INPUT_AS_NEEDED = 0x4000
};
 
// Symbol flags for the incremental symbol table.
// These flags are stored in the top two bits of
// the symbol index field.
 
enum Incremental_shlib_symbol_flags
{
// Symbol is defined in this library.
INCREMENTAL_SHLIB_SYM_DEF = 2,
// Symbol is defined in this library, with a COPY relocation.
INCREMENTAL_SHLIB_SYM_COPY = 3
};
 
static const int INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT = 30;
 
// Create an Incremental_binary object for FILE. Returns NULL is this is not
// possible, e.g. FILE is not an ELF file or has an unsupported target.
 
1012,9 → 1026,10
 
// Return the output symbol index for the Nth global symbol -- for shared
// libraries only. Sets *IS_DEF to TRUE if the symbol is defined in this
// input file.
// input file. Sets *IS_COPY to TRUE if the symbol was copied from this
// input file with a COPY relocation.
unsigned int
get_output_symbol_index(unsigned int n, bool* is_def)
get_output_symbol_index(unsigned int n, bool* is_def, bool* is_copy)
{
gold_assert(this->type() == INCREMENTAL_INPUT_SHARED_LIBRARY);
const unsigned char* p = (this->inputs_->p_
1021,8 → 1036,23
+ this->info_offset_ + 8
+ n * 4);
unsigned int output_symndx = Swap32::readval(p);
*is_def = (output_symndx & (1U << 31)) != 0;
return output_symndx & ((1U << 31) - 1);
unsigned int flags = output_symndx >> INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT;
output_symndx &= ((1U << INCREMENTAL_SHLIB_SYM_FLAGS_SHIFT) - 1);
switch (flags)
{
case INCREMENTAL_SHLIB_SYM_DEF:
*is_def = true;
*is_copy = false;
break;
case INCREMENTAL_SHLIB_SYM_COPY:
*is_def = true;
*is_copy = true;
break;
default:
*is_def = false;
*is_copy = false;
}
return output_symndx;
}
 
private:
1397,6 → 1427,11
process_got_plt(Symbol_table* symtab, Layout* layout)
{ this->do_process_got_plt(symtab, layout); }
 
// Emit COPY relocations from the existing output file.
void
emit_copy_relocs(Symbol_table* symtab)
{ this->do_emit_copy_relocs(symtab); }
 
// Apply incremental relocations for symbols whose values have changed.
void
apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
1479,6 → 1514,10
virtual void
do_process_got_plt(Symbol_table* symtab, Layout* layout) = 0;
 
// Emit COPY relocations from the existing output file.
virtual void
do_emit_copy_relocs(Symbol_table* symtab) = 0;
 
// Apply incremental relocations for symbols whose values have changed.
virtual void
do_apply_incremental_relocs(const Symbol_table*, Layout*, Output_file*) = 0;
1514,9 → 1553,9
const elfcpp::Ehdr<size, big_endian>& ehdr,
Target* target)
: Incremental_binary(output, target), elf_file_(this, ehdr),
input_objects_(), section_map_(), symbol_map_(), main_symtab_loc_(),
main_strtab_loc_(), has_incremental_info_(false), inputs_reader_(),
symtab_reader_(), relocs_reader_(), got_plt_reader_(),
input_objects_(), section_map_(), symbol_map_(), copy_relocs_(),
main_symtab_loc_(), main_strtab_loc_(), has_incremental_info_(false),
inputs_reader_(), symtab_reader_(), relocs_reader_(), got_plt_reader_(),
input_entry_readers_()
{ this->setup_readers(); }
 
1558,6 → 1597,11
global_symbol(unsigned int symndx) const
{ return this->symbol_map_[symndx]; }
 
// Add a COPY relocation for a global symbol.
void
add_copy_reloc(Symbol* gsym, Output_section* os, off_t offset)
{ this->copy_relocs_.push_back(Copy_reloc(gsym, os, offset)); }
 
// Readers for the incremental info sections.
 
const Incremental_inputs_reader<size, big_endian>&
1606,6 → 1650,10
virtual void
do_process_got_plt(Symbol_table* symtab, Layout* layout);
 
// Emit COPY relocations from the existing output file.
virtual void
do_emit_copy_relocs(Symbol_table* symtab);
 
// Apply incremental relocations for symbols whose values have changed.
virtual void
do_apply_incremental_relocs(const Symbol_table* symtab, Layout* layout,
1664,6 → 1712,22
}
 
private:
// List of symbols that need COPY relocations.
struct Copy_reloc
{
Copy_reloc(Symbol* sym, Output_section* os, off_t off)
: symbol(sym), output_section(os), offset(off)
{ }
 
// The global symbol to copy.
Symbol* symbol;
// The output section into which the symbol was copied.
Output_section* output_section;
// The offset within that output section.
off_t offset;
};
typedef std::vector<Copy_reloc> Copy_relocs;
 
bool
find_incremental_inputs_sections(unsigned int* p_inputs_shndx,
unsigned int* p_symtab_shndx,
1687,6 → 1751,9
// Map global symbols from the input file to the symbol table.
std::vector<Symbol*> symbol_map_;
 
// List of symbols that need COPY relocations.
Copy_relocs copy_relocs_;
 
// Locations of the main symbol table and symbol string table.
Location main_symtab_loc_;
Location main_strtab_loc_;
/layout.cc
2957,7 → 2957,7
if (!are_addresses_set
&& !has_relro
&& aligned_addr != addr
&& !parameters->incremental_update())
&& !parameters->incremental())
{
uint64_t first_off = (common_pagesize
- (aligned_addr
3125,9 → 3125,9
if (is_debugging_enabled(DEBUG_INCREMENTAL))
this->free_list_.dump();
gold_assert((*p)->output_section() != NULL);
gold_fatal(_("out of patch space for section %s; "
"relink with --incremental-full"),
(*p)->output_section()->name());
gold_fallback(_("out of patch space for section %s; "
"relink with --incremental-full"),
(*p)->output_section()->name());
}
(*p)->set_file_offset(off);
(*p)->finalize_data_size();
3134,9 → 3134,9
if ((*p)->data_size() > current_size)
{
gold_assert((*p)->output_section() != NULL);
gold_fatal(_("%s: section changed size; "
"relink with --incremental-full"),
(*p)->output_section()->name());
gold_fallback(_("%s: section changed size; "
"relink with --incremental-full"),
(*p)->output_section()->name());
}
gold_debug(DEBUG_INCREMENTAL,
"set_section_offsets: %08lx %08lx %s",
3391,8 → 3391,8
{
symtab_off = this->allocate(off, align, *poff);
if (off == -1)
gold_fatal(_("out of patch space for symbol table; "
"relink with --incremental-full"));
gold_fallback(_("out of patch space for symbol table; "
"relink with --incremental-full"));
gold_debug(DEBUG_INCREMENTAL,
"create_symtab_sections: %08lx %08lx .symtab",
static_cast<long>(symtab_off),
3462,8 → 3462,8
oshdrs->pre_finalize_data_size();
off = this->allocate(oshdrs->data_size(), oshdrs->addralign(), *poff);
if (off == -1)
gold_fatal(_("out of patch space for section header table; "
"relink with --incremental-full"));
gold_fallback(_("out of patch space for section header table; "
"relink with --incremental-full"));
gold_debug(DEBUG_INCREMENTAL,
"create_shdrs: %08lx %08lx (section header table)",
static_cast<long>(off),

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.