relocatable test.
ld2_LDADD = $(ldadd_var)
ld2_LDFLAGS = -Bgcctestdir2/
-check_PROGRAMS = ld1 ld2
-
bootstrap-test: ld2
rm -f $@
echo "#!/bin/sh" > $@
echo "cmp ld1 ld2" > $@
chmod +x $@
-TESTS = bootstrap-test
+libgold-1-r.o: gcctestdir1/ld libgold.a
+ gcctestdir1/ld -o $@ -r --whole-archive libgold.a
+
+ld1_r_SOURCES = $(sources_var)
+ld1_r_DEPENDENCIES = libgold-1-r.o $(deps_var) gcctestdir1/ld
+ld1_r_LDADD = libgold-1-r.o $(ldadd_var)
+ld1_r_LDFLAGS = -Bgcctestdir1/
+
+gcctestdir2-r/ld: ld1-r
+ test -d gcctestdir2-r || mkdir -p gcctestdir2-r
+ rm -f gcctestdir2-r/ld
+ (cd gcctestdir2-r && $(LN_S) ../ld1-r ld)
+
+libgold-2-r.o: gcctestdir2-r/ld libgold.a
+ gcctestdir2-r/ld -o $@ -r --whole-archive libgold.a
+
+ld2_r_SOURCES = $(sources_var)
+ld2_r_DEPENDENCIES = libgold-2-r.o $(deps_var) gcctestdir2-r/ld
+ld2_r_LDADD = libgold-2-r.o $(ldadd_var)
+ld2_r_LDFLAGS = -Bgcctestdir2-r/
+
+bootstrap-test-r: ld2-r
+ rm -f $@
+ echo "#!/bin/sh" > $@
+ echo "cmp ld1-r ld2-r" > $@
+ chmod +x $@
+
+check_PROGRAMS = ld1 ld2 ld1-r ld2-r
+TESTS = bootstrap-test bootstrap-test-r
endif
endif
target_triplet = @target@
noinst_PROGRAMS = ld-new$(EXEEXT)
@GCC_TRUE@@NATIVE_LINKER_TRUE@check_PROGRAMS = ld1$(EXEEXT) \
-@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2$(EXEEXT) ld1-r$(EXEEXT) \
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ ld2-r$(EXEEXT)
DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
$(srcdir)/../config.sub $(srcdir)/../depcomp \
$(srcdir)/../install-sh $(srcdir)/../missing \
am__ld1_SOURCES_DIST = main.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4)
ld1_OBJECTS = $(am_ld1_OBJECTS)
+am__ld1_r_SOURCES_DIST = main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_r_OBJECTS = $(am__objects_4)
+ld1_r_OBJECTS = $(am_ld1_r_OBJECTS)
am__ld2_SOURCES_DIST = main.cc
@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld2_OBJECTS = $(am__objects_4)
ld2_OBJECTS = $(am_ld2_OBJECTS)
+am__ld2_r_SOURCES_DIST = main.cc
+@GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld2_r_OBJECTS = $(am__objects_4)
+ld2_r_OBJECTS = $(am_ld2_r_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
-o $@
YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
- $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) $(ld2_SOURCES)
+ $(EXTRA_ld_new_SOURCES) $(ld1_SOURCES) $(ld1_r_SOURCES) \
+ $(ld2_SOURCES) $(ld2_r_SOURCES)
DIST_SOURCES = $(libgold_a_SOURCES) $(ld_new_SOURCES) \
$(EXTRA_ld_new_SOURCES) $(am__ld1_SOURCES_DIST) \
- $(am__ld2_SOURCES_DIST)
+ $(am__ld1_r_SOURCES_DIST) $(am__ld2_SOURCES_DIST) \
+ $(am__ld2_r_SOURCES_DIST)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_DEPENDENCIES = $(deps_var) gcctestdir2/ld
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDADD = $(ldadd_var)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_LDFLAGS = -Bgcctestdir2/
-@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_DEPENDENCIES = libgold-1-r.o $(deps_var) gcctestdir1/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_LDADD = libgold-1-r.o $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld1_r_LDFLAGS = -Bgcctestdir1/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_SOURCES = $(sources_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_DEPENDENCIES = libgold-2-r.o $(deps_var) gcctestdir2-r/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDADD = libgold-2-r.o $(ldadd_var)
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ld2_r_LDFLAGS = -Bgcctestdir2-r/
+@GCC_TRUE@@NATIVE_LINKER_TRUE@TESTS = bootstrap-test bootstrap-test-r
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
ld1$(EXEEXT): $(ld1_OBJECTS) $(ld1_DEPENDENCIES)
@rm -f ld1$(EXEEXT)
$(CXXLINK) $(ld1_LDFLAGS) $(ld1_OBJECTS) $(ld1_LDADD) $(LIBS)
+ld1-r$(EXEEXT): $(ld1_r_OBJECTS) $(ld1_r_DEPENDENCIES)
+ @rm -f ld1-r$(EXEEXT)
+ $(CXXLINK) $(ld1_r_LDFLAGS) $(ld1_r_OBJECTS) $(ld1_r_LDADD) $(LIBS)
ld2$(EXEEXT): $(ld2_OBJECTS) $(ld2_DEPENDENCIES)
@rm -f ld2$(EXEEXT)
$(CXXLINK) $(ld2_LDFLAGS) $(ld2_OBJECTS) $(ld2_LDADD) $(LIBS)
+ld2-r$(EXEEXT): $(ld2_r_OBJECTS) $(ld2_r_DEPENDENCIES)
+ @rm -f ld2-r$(EXEEXT)
+ $(CXXLINK) $(ld2_r_LDFLAGS) $(ld2_r_OBJECTS) $(ld2_r_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "#!/bin/sh" > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "cmp ld1 ld2" > $@
@GCC_TRUE@@NATIVE_LINKER_TRUE@ chmod +x $@
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@libgold-1-r.o: gcctestdir1/ld libgold.a
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir1/ld -o $@ -r --whole-archive libgold.a
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@gcctestdir2-r/ld: ld1-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ test -d gcctestdir2-r || mkdir -p gcctestdir2-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f gcctestdir2-r/ld
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ (cd gcctestdir2-r && $(LN_S) ../ld1-r ld)
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@libgold-2-r.o: gcctestdir2-r/ld libgold.a
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ gcctestdir2-r/ld -o $@ -r --whole-archive libgold.a
+
+@GCC_TRUE@@NATIVE_LINKER_TRUE@bootstrap-test-r: ld2-r
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ rm -f $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "#!/bin/sh" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ echo "cmp ld1-r ld2-r" > $@
+@GCC_TRUE@@NATIVE_LINKER_TRUE@ chmod +x $@
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
layout->define_section_symbols(symtab);
}
+ // Make sure we have symbols for any required group signatures.
+ layout->define_group_signatures(symtab);
+
// Read the relocations of the input files. We do this to find
// which symbols are used by relocations which require a GOT and/or
// a PLT entry, or a COPY reloc. When we implement garbage
unattached_section_list_(), special_output_list_(),
section_headers_(NULL), tls_segment_(NULL), symtab_section_(NULL),
dynsym_section_(NULL), dynamic_section_(NULL), dynamic_data_(NULL),
- eh_frame_section_(NULL), output_file_size_(-1),
+ eh_frame_section_(NULL), group_signatures_(), output_file_size_(-1),
input_requires_executable_stack_(false),
input_with_gnu_stack_note_(false),
input_without_gnu_stack_note_(false),
shdr.get_sh_flags());
// We need to find a symbol with the signature in the symbol table.
- // This is a hack to force that to happen.
+ // If we don't find one now, we need to look again later.
Symbol* sym = symtab->lookup(signature, NULL);
- if (sym == NULL)
- sym = symtab->define_as_constant(signature, NULL, 0, 0,
- elfcpp::STT_NOTYPE,
- elfcpp::STB_WEAK,
- elfcpp::STV_HIDDEN, 0, false);
+ if (sym != NULL)
+ os->set_info_symndx(sym);
+ else
+ {
+ // We will wind up using a symbol whose name is the signature.
+ // So just put the signature in the symbol name pool to save it.
+ signature = symtab->canonicalize_name(signature);
+ this->group_signatures_.push_back(Group_signature(os, signature));
+ }
os->set_should_link_to_symtab();
- os->set_info_symndx(sym);
os->set_entsize(4);
section_size_type entry_count =
}
}
+// Define symbols for group signatures.
+
+void
+Layout::define_group_signatures(Symbol_table* symtab)
+{
+ for (Group_signatures::iterator p = this->group_signatures_.begin();
+ p != this->group_signatures_.end();
+ ++p)
+ {
+ Symbol* sym = symtab->lookup(p->signature, NULL);
+ if (sym != NULL)
+ p->section->set_info_symndx(sym);
+ else
+ {
+ // Force the name of the group section to the group
+ // signature, and use the group's section symbol as the
+ // signature symbol.
+ if (strcmp(p->section->name(), p->signature) != 0)
+ {
+ const char* name = this->namepool_.add(p->signature,
+ true, NULL);
+ p->section->set_name(name);
+ }
+ p->section->set_needs_symtab_index();
+ p->section->set_info_section_symndx(p->section);
+ }
+ }
+
+ this->group_signatures_.clear();
+}
+
// Find the first read-only PT_LOAD segment, creating one if
// necessary.
define_script_symbols(Symbol_table* symtab)
{ this->script_options_->add_symbols_to_table(symtab); }
+ // Define symbols for group signatures.
+ void
+ define_group_signatures(Symbol_table*);
+
// Return the Stringpool used for symbol names.
const Stringpool*
sympool() const
static const Linkonce_mapping linkonce_mapping[];
static const int linkonce_mapping_count;
+ // During a relocatable link, a list of group sections and
+ // signatures.
+ struct Group_signature
+ {
+ // The group section.
+ Output_section* section;
+ // The signature.
+ const char* signature;
+
+ Group_signature()
+ : section(NULL), signature(NULL)
+ { }
+
+ Group_signature(Output_section* sectiona, const char* signaturea)
+ : section(sectiona), signature(signaturea)
+ { }
+ };
+ typedef std::vector<Group_signature> Group_signatures;
+
// Create a .note section for gold.
void
create_gold_note();
Eh_frame* eh_frame_data_;
// The exception frame header output section if there is one.
Output_section* eh_frame_hdr_section_;
+ // A list of group sections and their signatures.
+ Group_signatures group_signatures_;
// The size of the output file.
off_t output_file_size_;
// Whether we have seen an object file marked to require an
requires_postprocessing_(false),
found_in_sections_clause_(false),
has_load_address_(false),
+ info_uses_section_index_(false),
tls_offset_(0)
{
// An unallocated section has no address. Forcing this means that
oshdr->put_sh_type(this->type_);
elfcpp::Elf_Xword flags = this->flags_;
- if (this->info_section_ != NULL)
+ if (this->info_section_ != NULL && this->info_uses_section_index_)
flags |= elfcpp::SHF_INFO_LINK;
oshdr->put_sh_flags(flags);
oshdr->put_sh_link(layout->dynsym_section()->out_shndx());
else
oshdr->put_sh_link(this->link_);
+
+ elfcpp::Elf_Word info;
if (this->info_section_ != NULL)
- oshdr->put_sh_info(this->info_section_->out_shndx());
+ {
+ if (this->info_uses_section_index_)
+ info = this->info_section_->out_shndx();
+ else
+ info = this->info_section_->symtab_index();
+ }
else if (this->info_symndx_ != NULL)
- oshdr->put_sh_info(this->info_symndx_->symtab_index());
+ info = this->info_symndx_->symtab_index();
else
- oshdr->put_sh_info(this->info_);
+ info = this->info_;
+ oshdr->put_sh_info(info);
+
oshdr->put_sh_addralign(this->addralign_);
oshdr->put_sh_entsize(this->entsize_);
}
unsigned int
info() const
{
- gold_assert(this->info_section_ == NULL);
+ gold_assert(this->info_section_ == NULL
+ && this->info_symndx_ == NULL);
return this->info_;
}
// Set the info field to the output section index of a section.
void
- set_info_section(const Output_data* od)
+ set_info_section(const Output_section* os)
{
- gold_assert(this->info_symndx_ == NULL && this->info_ == 0);
- this->info_section_ = od;
+ gold_assert((this->info_section_ == NULL
+ || (this->info_section_ == os
+ && this->info_uses_section_index_))
+ && this->info_symndx_ == NULL
+ && this->info_ == 0);
+ this->info_section_ = os;
+ this->info_uses_section_index_= true;
}
// Set the info field to the symbol table index of a symbol.
void
set_info_symndx(const Symbol* sym)
{
- gold_assert(this->info_section_ == NULL && this->info_ == 0);
+ gold_assert(this->info_section_ == NULL
+ && (this->info_symndx_ == NULL
+ || this->info_symndx_ == sym)
+ && this->info_ == 0);
this->info_symndx_ = sym;
}
+ // Set the info field to the symbol table index of a section symbol.
+ void
+ set_info_section_symndx(const Output_section* os)
+ {
+ gold_assert((this->info_section_ == NULL
+ || (this->info_section_ == os
+ && !this->info_uses_section_index_))
+ && this->info_symndx_ == NULL
+ && this->info_ == 0);
+ this->info_section_ = os;
+ this->info_uses_section_index_ = false;
+ }
+
// Set the info field to a constant.
void
set_info(unsigned int v)
{
- gold_assert(this->info_section_ == NULL && this->info_symndx_ == NULL);
+ gold_assert(this->info_section_ == NULL
+ && this->info_symndx_ == NULL
+ && (this->info_ == 0
+ || this->info_ == v));
this->info_ = v;
}
postprocessing_buffer_size() const
{ return this->current_data_size_for_child(); }
+ // Modify the section name. This is only permitted for an
+ // unallocated section, and only before the size has been finalized.
+ // Otherwise the name will not get into Layout::namepool_.
+ void
+ set_name(const char* newname)
+ {
+ gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
+ gold_assert(!this->is_data_size_valid());
+ this->name_ = newname;
+ }
+
// Return whether the offset OFFSET in the input section SHNDX in
// object OBJECT is being included in the link.
bool
do_tls_offset() const
{ return this->tls_offset_; }
- // Modify the section name. This is only permitted for an
- // unallocated section, and only before the size has been finalized.
- // Otherwise the name will not get into Layout::namepool_.
- void
- set_name(const char* newname)
- {
- gold_assert((this->flags_ & elfcpp::SHF_ALLOC) == 0);
- gold_assert(!this->is_data_size_valid());
- this->name_ = newname;
- }
-
// This may be implemented by a child class.
virtual void
do_finalize_name(Layout*)
// If link_section_ is NULL, this is the link field.
unsigned int link_;
// Set the section info field to the index of this section.
- const Output_data* info_section_;
+ const Output_section* info_section_;
// If info_section_ is NULL, set the info field to the symbol table
// index of this symbol.
const Symbol* info_symndx_;
bool found_in_sections_clause_ : 1;
// Whether this section has an explicitly specified load address.
bool has_load_address_ : 1;
+ // True if the info_section_ field means the section index of the
+ // section, false if it means the symbol index of the corresponding
+ // section symbol.
+ bool info_uses_section_index_ : 1;
// For SHT_TLS sections, the offset of this section relative to the base
// of the TLS segment.
uint64_t tls_offset_;