From: Alan Modra Date: Tue, 12 Mar 2013 00:42:14 +0000 (+0000) Subject: * gc.h (gc_process_relocs): Look through function descriptors X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=57420c208463c85912f56abf49ce9f3546f9fbe7;p=binutils-gdb.git * gc.h (gc_process_relocs): Look through function descriptors to determine shndx, symvalue and addend used by ICF. Tidy variable duplication. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index fcbfed4c792..e859a5e1f2a 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,9 @@ +2013-03-12 Alan Modra + + * gc.h (gc_process_relocs): Look through function descriptors + to determine shndx, symvalue and addend used by ICF. Tidy + variable duplication. + 2013-03-11 Alan Modra * gold.cc (queue_middle_tasks): Move detect_odr_violations.. diff --git a/gold/gc.h b/gold/gc.h index a1691514273..6930aced431 100644 --- a/gold/gc.h +++ b/gold/gc.h @@ -235,30 +235,45 @@ gc_process_relocs( Reloc_types::get_reloc_addend_noerror(&reloc); Object* dst_obj; unsigned int dst_indx; - typename elfcpp::Elf_types::Elf_Addr dst_off; + typedef typename elfcpp::Elf_types::Elf_Addr Address; + Address dst_off; if (r_sym < local_count) { gold_assert(plocal_syms != NULL); typename elfcpp::Sym lsym(plocal_syms + r_sym * sym_size); - unsigned int shndx = lsym.get_st_shndx(); + dst_indx = lsym.get_st_shndx(); bool is_ordinary; - shndx = src_obj->adjust_sym_shndx(r_sym, shndx, &is_ordinary); + dst_indx = src_obj->adjust_sym_shndx(r_sym, dst_indx, &is_ordinary); dst_obj = src_obj; - dst_indx = shndx; - dst_off = lsym.get_st_value(); + dst_off = lsym.get_st_value() + addend; if (is_icf_tracked) { + Address symvalue = dst_off - addend; if (is_ordinary) - (*secvec).push_back(Section_id(dst_obj, dst_indx)); + { + Symbol_location loc; + loc.object = dst_obj; + loc.shndx = dst_indx; + loc.offset = convert_types(dst_off); + // Look through function descriptors. + parameters->target().function_location(&loc); + if (loc.shndx != dst_indx) + { + // Modify symvalue/addend to the code entry. + symvalue = loc.offset; + addend = 0; + } + (*secvec).push_back(Section_id(loc.object, loc.shndx)); + } else (*secvec).push_back(Section_id(NULL, 0)); (*symvec).push_back(NULL); - long long symvalue = static_cast(lsym.get_st_value()); - (*addendvec).push_back(std::make_pair(symvalue, - static_cast(addend))); + (*addendvec).push_back(std::make_pair( + static_cast(symvalue), + static_cast(addend))); uint64_t reloc_offset = convert_to_section_size_type(reloc.get_r_offset()); (*offsetvec).push_back(reloc_offset); @@ -279,7 +294,7 @@ gc_process_relocs( symtab->icf()->set_section_has_function_pointers( src_obj, lsym.get_st_shndx()); - if (!is_ordinary || shndx == src_indx) + if (!is_ordinary || dst_indx == src_indx) continue; } else @@ -291,14 +306,14 @@ gc_process_relocs( dst_obj = NULL; dst_indx = 0; - dst_off = 0; bool is_ordinary = false; if (gsym->source() == Symbol::FROM_OBJECT) { dst_obj = gsym->object(); dst_indx = gsym->shndx(&is_ordinary); - dst_off = static_cast*>(gsym)->value(); } + dst_off = static_cast*>(gsym)->value(); + dst_off += addend; // When doing safe folding, check to see if this relocation is that // of a function pointer being taken. @@ -326,17 +341,29 @@ gc_process_relocs( } if (is_icf_tracked) { + Address symvalue = dst_off - addend; if (is_ordinary && gsym->source() == Symbol::FROM_OBJECT) - (*secvec).push_back(Section_id(dst_obj, dst_indx)); + { + Symbol_location loc; + loc.object = dst_obj; + loc.shndx = dst_indx; + loc.offset = convert_types(dst_off); + // Look through function descriptors. + parameters->target().function_location(&loc); + if (loc.shndx != dst_indx) + { + // Modify symvalue/addend to the code entry. + symvalue = loc.offset; + addend = 0; + } + (*secvec).push_back(Section_id(loc.object, loc.shndx)); + } else (*secvec).push_back(Section_id(NULL, 0)); (*symvec).push_back(gsym); - Sized_symbol* sized_gsym = - static_cast* >(gsym); - long long symvalue = - static_cast(sized_gsym->value()); - (*addendvec).push_back(std::make_pair(symvalue, - static_cast(addend))); + (*addendvec).push_back(std::make_pair( + static_cast(symvalue), + static_cast(addend))); uint64_t reloc_offset = convert_to_section_size_type(reloc.get_r_offset()); (*offsetvec).push_back(reloc_offset); @@ -353,7 +380,6 @@ gc_process_relocs( if (parameters->options().gc_sections()) { symtab->gc()->add_reference(src_obj, src_indx, dst_obj, dst_indx); - dst_off += addend; parameters->sized_target() ->gc_add_reference(symtab, src_obj, src_indx, dst_obj, dst_indx, dst_off);