diff options
-rw-r--r-- | gold/output.cc | 77 | ||||
-rw-r--r-- | gold/output.h | 77 |
2 files changed, 79 insertions, 75 deletions
diff --git a/gold/output.cc b/gold/output.cc index 75f54f0..c5f7eef 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -1461,15 +1461,15 @@ Output_data_got<got_size, big_endian>::Got_entry::write( template<int got_size, bool big_endian> bool -Output_data_got<got_size, big_endian>::add_global( - Symbol* gsym, - unsigned int got_type) +Output_data_got<got_size, big_endian>::add_global(Symbol* gsym, + unsigned int got_type, + uint64_t addend) { - if (gsym->has_got_offset(got_type)) + if (gsym->has_got_offset(got_type, addend)) return false; - unsigned int got_offset = this->add_got_entry(Got_entry(gsym, false)); - gsym->set_got_offset(got_type, got_offset); + unsigned int got_offset = this->add_got_entry(Got_entry(gsym, false, addend)); + gsym->set_got_offset(got_type, got_offset, addend); return true; } @@ -1478,13 +1478,14 @@ Output_data_got<got_size, big_endian>::add_global( template<int got_size, bool big_endian> bool Output_data_got<got_size, big_endian>::add_global_plt(Symbol* gsym, - unsigned int got_type) + unsigned int got_type, + uint64_t addend) { - if (gsym->has_got_offset(got_type)) + if (gsym->has_got_offset(got_type, addend)) return false; - unsigned int got_offset = this->add_got_entry(Got_entry(gsym, true)); - gsym->set_got_offset(got_type, got_offset); + unsigned int got_offset = this->add_got_entry(Got_entry(gsym, true, addend)); + gsym->set_got_offset(got_type, got_offset, addend); return true; } @@ -1497,14 +1498,15 @@ Output_data_got<got_size, big_endian>::add_global_with_rel( Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type) + unsigned int r_type, + uint64_t addend) { - if (gsym->has_got_offset(got_type)) + if (gsym->has_got_offset(got_type, addend)) return; unsigned int got_offset = this->add_got_entry(Got_entry()); - gsym->set_got_offset(got_type, got_offset); - rel_dyn->add_global_generic(gsym, r_type, this, got_offset, 0); + gsym->set_got_offset(got_type, got_offset, addend); + rel_dyn->add_global_generic(gsym, r_type, this, got_offset, addend); } // Add a pair of entries for a global symbol to the GOT, and add @@ -1517,18 +1519,19 @@ Output_data_got<got_size, big_endian>::add_global_pair_with_rel( unsigned int got_type, Output_data_reloc_generic* rel_dyn, unsigned int r_type_1, - unsigned int r_type_2) + unsigned int r_type_2, + uint64_t addend) { - if (gsym->has_got_offset(got_type)) + if (gsym->has_got_offset(got_type, addend)) return; unsigned int got_offset = this->add_got_entry_pair(Got_entry(), Got_entry()); - gsym->set_got_offset(got_type, got_offset); - rel_dyn->add_global_generic(gsym, r_type_1, this, got_offset, 0); + gsym->set_got_offset(got_type, got_offset, addend); + rel_dyn->add_global_generic(gsym, r_type_1, this, got_offset, addend); if (r_type_2 != 0) rel_dyn->add_global_generic(gsym, r_type_2, this, - got_offset + got_size / 8, 0); + got_offset + got_size / 8, addend); } // Add an entry for a local symbol plus ADDEND to the GOT. This returns @@ -1559,14 +1562,15 @@ bool Output_data_got<got_size, big_endian>::add_local_plt( Relobj* object, unsigned int symndx, - unsigned int got_type) + unsigned int got_type, + uint64_t addend) { - if (object->local_has_got_offset(symndx, got_type)) + if (object->local_has_got_offset(symndx, got_type, addend)) return false; unsigned int got_offset = this->add_got_entry(Got_entry(object, symndx, - true)); - object->set_local_got_offset(symndx, got_type, got_offset); + true, addend)); + object->set_local_got_offset(symndx, got_type, got_offset, addend); return true; } @@ -1580,7 +1584,8 @@ Output_data_got<got_size, big_endian>::add_local_with_rel( unsigned int symndx, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type, uint64_t addend) + unsigned int r_type, + uint64_t addend) { if (object->local_has_got_offset(symndx, got_type, addend)) return; @@ -1604,7 +1609,8 @@ Output_data_got<got_size, big_endian>::add_local_pair_with_rel( unsigned int shndx, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type, uint64_t addend) + unsigned int r_type, + uint64_t addend) { if (object->local_has_got_offset(symndx, got_type, addend)) return; @@ -1628,16 +1634,17 @@ Output_data_got<got_size, big_endian>::add_local_tls_pair( unsigned int symndx, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type) + unsigned int r_type, + uint64_t addend) { - if (object->local_has_got_offset(symndx, got_type)) + if (object->local_has_got_offset(symndx, got_type, addend)) return; unsigned int got_offset = this->add_got_entry_pair(Got_entry(), - Got_entry(object, symndx, true)); - object->set_local_got_offset(symndx, got_type, got_offset); - rel_dyn->add_local_generic(object, 0, r_type, this, got_offset, 0); + Got_entry(object, symndx, true, addend)); + object->set_local_got_offset(symndx, got_type, got_offset, addend); + rel_dyn->add_local_generic(object, 0, r_type, this, got_offset, addend); } // Reserve a slot in the GOT for a local symbol or the second slot of a pair. @@ -1648,10 +1655,11 @@ Output_data_got<got_size, big_endian>::reserve_local( unsigned int i, Relobj* object, unsigned int sym_index, - unsigned int got_type) + unsigned int got_type, + uint64_t addend) { this->do_reserve_slot(i); - object->set_local_got_offset(sym_index, got_type, this->got_offset(i)); + object->set_local_got_offset(sym_index, got_type, this->got_offset(i), addend); } // Reserve a slot in the GOT for a global symbol. @@ -1661,10 +1669,11 @@ void Output_data_got<got_size, big_endian>::reserve_global( unsigned int i, Symbol* gsym, - unsigned int got_type) + unsigned int got_type, + uint64_t addend) { this->do_reserve_slot(i); - gsym->set_got_offset(got_type, this->got_offset(i)); + gsym->set_got_offset(got_type, this->got_offset(i), addend); } // Write out the GOT. diff --git a/gold/output.h b/gold/output.h index 726c93b..bf4b54e 100644 --- a/gold/output.h +++ b/gold/output.h @@ -2459,34 +2459,38 @@ class Output_data_got : public Output_data_got_base this->free_list_.init(data_size, false); } - // Add an entry for a global symbol to the GOT. Return true if this - // is a new GOT entry, false if the symbol was already in the GOT. + // Add an entry for a global symbol GSYM plus ADDEND to the GOT. + // Return true if this is a new GOT entry, false if the symbol plus + // addend was already in the GOT. bool - add_global(Symbol* gsym, unsigned int got_type); + add_global(Symbol* gsym, unsigned int got_type, uint64_t addend = 0); // Like add_global, but use the PLT offset of the global symbol if // it has one. bool - add_global_plt(Symbol* gsym, unsigned int got_type); + add_global_plt(Symbol* gsym, unsigned int got_type, uint64_t addend = 0); // Like add_global, but for a TLS symbol where the value will be // offset using Target::tls_offset_for_global. bool - add_global_tls(Symbol* gsym, unsigned int got_type) - { return add_global_plt(gsym, got_type); } + add_global_tls(Symbol* gsym, unsigned int got_type, uint64_t addend = 0) + { return this->add_global_plt(gsym, got_type, addend); } - // Add an entry for a global symbol to the GOT, and add a dynamic - // relocation of type R_TYPE for the GOT entry. + // Add an entry for a global symbol GSYM plus ADDEND to the GOT, and + // add a dynamic relocation of type R_TYPE for the GOT entry. void add_global_with_rel(Symbol* gsym, unsigned int got_type, - Output_data_reloc_generic* rel_dyn, unsigned int r_type); + Output_data_reloc_generic* rel_dyn, unsigned int r_type, + uint64_t addend = 0); - // Add a pair of entries for a global symbol to the GOT, and add - // dynamic relocations of type R_TYPE_1 and R_TYPE_2, respectively. + // Add a pair of entries for a global symbol GSYM plus ADDEND to the + // GOT, and add dynamic relocations of type R_TYPE_1 and R_TYPE_2, + // respectively. void add_global_pair_with_rel(Symbol* gsym, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type_1, unsigned int r_type_2); + unsigned int r_type_1, unsigned int r_type_2, + uint64_t addend = 0); // Add an entry for a local symbol plus ADDEND to the GOT. This returns // true if this is a new GOT entry, false if the symbol already has a GOT @@ -2498,13 +2502,15 @@ class Output_data_got : public Output_data_got_base // Like add_local, but use the PLT offset of the local symbol if it // has one. bool - add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type); + add_local_plt(Relobj* object, unsigned int sym_index, unsigned int got_type, + uint64_t addend = 0); // Like add_local, but for a TLS symbol where the value will be // offset using Target::tls_offset_for_local. bool - add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type) - { return add_local_plt(object, sym_index, got_type); } + add_local_tls(Relobj* object, unsigned int sym_index, unsigned int got_type, + uint64_t addend = 0) + { return this->add_local_plt(object, sym_index, got_type, addend); } // Add an entry for a local symbol plus ADDEND to the GOT, and add a dynamic // relocation of type R_TYPE for the GOT entry. @@ -2524,15 +2530,16 @@ class Output_data_got : public Output_data_got_base Output_data_reloc_generic* rel_dyn, unsigned int r_type, uint64_t addend = 0); - // Add a pair of entries for a local symbol to the GOT, and add - // a dynamic relocation of type R_TYPE using STN_UNDEF on the first. - // The first got entry will have a value of zero, the second the - // value of the local symbol offset by Target::tls_offset_for_local. + // Add a pair of entries for a local symbol plus ADDEND to the GOT, + // and add a dynamic relocation of type R_TYPE using STN_UNDEF on + // the first. The first got entry will have a value of zero, the + // second the value of the local symbol plus ADDEND offset by + // Target::tls_offset_for_local. void add_local_tls_pair(Relobj* object, unsigned int sym_index, unsigned int got_type, Output_data_reloc_generic* rel_dyn, - unsigned int r_type); + unsigned int r_type, uint64_t addend = 0); // Add a constant to the GOT. This returns the offset of the new // entry from the start of the GOT. @@ -2553,14 +2560,15 @@ class Output_data_got : public Output_data_got_base this->replace_got_entry(i, Got_entry(constant)); } - // Reserve a slot in the GOT for a local symbol. + // Reserve a slot in the GOT for a local symbol plus ADDEND. void reserve_local(unsigned int i, Relobj* object, unsigned int sym_index, - unsigned int got_type); + unsigned int got_type, uint64_t addend = 0); - // Reserve a slot in the GOT for a global symbol. + // Reserve a slot in the GOT for a global symbol plus ADDEND. void - reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type); + reserve_global(unsigned int i, Symbol* gsym, unsigned int got_type, + uint64_t addend = 0); protected: // Write out the GOT table. @@ -2599,16 +2607,16 @@ class Output_data_got : public Output_data_got_base { this->u_.constant = 0; } // Create a global symbol entry. - Got_entry(Symbol* gsym, bool use_plt_or_tls_offset) + Got_entry(Symbol* gsym, bool use_plt_or_tls_offset, uint64_t addend) : local_sym_index_(GSYM_CODE), - use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0) + use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend) { this->u_.gsym = gsym; } // Create a local symbol entry. Got_entry(Relobj* object, unsigned int local_sym_index, - bool use_plt_or_tls_offset) + bool use_plt_or_tls_offset, uint64_t addend) : local_sym_index_(local_sym_index), - use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(0) + use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend) { gold_assert(local_sym_index != GSYM_CODE && local_sym_index != CONSTANT_CODE @@ -2617,19 +2625,6 @@ class Output_data_got : public Output_data_got_base this->u_.object = object; } - // Create a local symbol entry plus addend. - Got_entry(Relobj* object, unsigned int local_sym_index, - bool use_plt_or_tls_offset, uint64_t addend) - : local_sym_index_(local_sym_index), - use_plt_or_tls_offset_(use_plt_or_tls_offset), addend_(addend) - { - gold_assert(local_sym_index != GSYM_CODE - && local_sym_index != CONSTANT_CODE - && local_sym_index != RESERVED_CODE - && local_sym_index == this->local_sym_index_); - this->u_.object = object; - } - // Create a constant entry. The constant is a host value--it will // be swapped, if necessary, when it is written out. explicit Got_entry(Valtype constant) |