+// A reloc against a global symbol.
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Symbol* gsym,
+ unsigned int type,
+ Output_data* od,
+ Address address,
+ bool is_relative)
+ : address_(address), local_sym_index_(GSYM_CODE), type_(type),
+ is_relative_(is_relative), is_section_symbol_(false), shndx_(INVALID_CODE)
+{
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.gsym = gsym;
+ this->u2_.od = od;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+}
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Symbol* gsym,
+ unsigned int type,
+ Relobj* relobj,
+ unsigned int shndx,
+ Address address,
+ bool is_relative)
+ : address_(address), local_sym_index_(GSYM_CODE), type_(type),
+ is_relative_(is_relative), is_section_symbol_(false), shndx_(shndx)
+{
+ gold_assert(shndx != INVALID_CODE);
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.gsym = gsym;
+ this->u2_.relobj = relobj;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+}
+
+// A reloc against a local symbol.
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int local_sym_index,
+ unsigned int type,
+ Output_data* od,
+ Address address,
+ bool is_relative,
+ bool is_section_symbol)
+ : address_(address), local_sym_index_(local_sym_index), type_(type),
+ is_relative_(is_relative), is_section_symbol_(is_section_symbol),
+ shndx_(INVALID_CODE)
+{
+ gold_assert(local_sym_index != GSYM_CODE
+ && local_sym_index != INVALID_CODE);
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.relobj = relobj;
+ this->u2_.od = od;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+}
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Sized_relobj<size, big_endian>* relobj,
+ unsigned int local_sym_index,
+ unsigned int type,
+ unsigned int shndx,
+ Address address,
+ bool is_relative,
+ bool is_section_symbol)
+ : address_(address), local_sym_index_(local_sym_index), type_(type),
+ is_relative_(is_relative), is_section_symbol_(is_section_symbol),
+ shndx_(shndx)
+{
+ gold_assert(local_sym_index != GSYM_CODE
+ && local_sym_index != INVALID_CODE);
+ gold_assert(shndx != INVALID_CODE);
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.relobj = relobj;
+ this->u2_.relobj = relobj;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+}
+
+// A reloc against the STT_SECTION symbol of an output section.
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Output_section* os,
+ unsigned int type,
+ Output_data* od,
+ Address address)
+ : address_(address), local_sym_index_(SECTION_CODE), type_(type),
+ is_relative_(false), is_section_symbol_(true), shndx_(INVALID_CODE)
+{
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.os = os;
+ this->u2_.od = od;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+ else
+ os->set_needs_symtab_index();
+}
+
+template<bool dynamic, int size, bool big_endian>
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::Output_reloc(
+ Output_section* os,
+ unsigned int type,
+ Relobj* relobj,
+ unsigned int shndx,
+ Address address)
+ : address_(address), local_sym_index_(SECTION_CODE), type_(type),
+ is_relative_(false), is_section_symbol_(true), shndx_(shndx)
+{
+ gold_assert(shndx != INVALID_CODE);
+ // this->type_ is a bitfield; make sure TYPE fits.
+ gold_assert(this->type_ == type);
+ this->u1_.os = os;
+ this->u2_.relobj = relobj;
+ if (dynamic)
+ this->set_needs_dynsym_index();
+ else
+ os->set_needs_symtab_index();
+}
+
+// Record that we need a dynamic symbol index for this relocation.
+
+template<bool dynamic, int size, bool big_endian>
+void
+Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::
+set_needs_dynsym_index()
+{
+ if (this->is_relative_)
+ return;
+ switch (this->local_sym_index_)
+ {
+ case INVALID_CODE:
+ gold_unreachable();
+
+ case GSYM_CODE:
+ this->u1_.gsym->set_needs_dynsym_entry();
+ break;
+
+ case SECTION_CODE:
+ this->u1_.os->set_needs_dynsym_index();
+ break;
+
+ case 0:
+ break;
+
+ default:
+ {
+ const unsigned int lsi = this->local_sym_index_;
+ if (!this->is_section_symbol_)
+ this->u1_.relobj->set_needs_output_dynsym_entry(lsi);
+ else
+ {
+ section_offset_type dummy;
+ Output_section* os = this->u1_.relobj->output_section(lsi, &dummy);
+ gold_assert(os != NULL);
+ os->set_needs_dynsym_index();
+ }
+ }
+ break;
+ }
+}
+