X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fgc.h;h=cd5b539b4856903ee388aa83babc46ca95cb5072;hb=160f8a8f32f5566077e4a4b13943bc7c70bc5da2;hp=56b5e74fd88f0f42256ac2771b2371a33ebcb42a;hpb=2c54b4f42276b990ee7fd98a5f7c4629dac8f50b;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/gc.h b/gold/gc.h index 56b5e74fd8..cd5b539b48 100644 --- a/gold/gc.h +++ b/gold/gc.h @@ -1,6 +1,6 @@ // gc.h -- garbage collection of unused sections -// Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +// Copyright (C) 2009-2020 Free Software Foundation, Inc. // Written by Sriraman Tallam . // This file is part of gold. @@ -23,7 +23,6 @@ #ifndef GOLD_GC_H #define GOLD_GC_H -#include #include #include "elfcpp.h" @@ -39,9 +38,6 @@ class Object; template class Sized_relobj_file; -template -struct Reloc_types; - class Output_section; class General_options; class Layout; @@ -52,7 +48,7 @@ class Garbage_collection typedef Unordered_set Sections_reachable; typedef std::map Section_ref; - typedef std::queue Worklist_type; + typedef std::vector Worklist_type; // This maps the name of the section which can be represented as a C // identifier (cident) to the list of sections that have that name. // Different object files can have cident sections with the same name. @@ -88,7 +84,7 @@ class Garbage_collection do_transitive_closure(); bool - is_section_garbage(Object* obj, unsigned int shndx) + is_section_garbage(Relobj* obj, unsigned int shndx) { return (this->referenced_list().find(Section_id(obj, shndx)) == this->referenced_list().end()); } @@ -104,16 +100,13 @@ class Garbage_collection // Add a reference from the SRC_SHNDX-th section of SRC_OBJECT to // DST_SHNDX-th section of DST_OBJECT. void - add_reference(Object* src_object, unsigned int src_shndx, - Object* dst_object, unsigned int dst_shndx) + add_reference(Relobj* src_object, unsigned int src_shndx, + Relobj* dst_object, unsigned int dst_shndx) { Section_id src_id(src_object, src_shndx); Section_id dst_id(dst_object, dst_shndx); - Section_ref::iterator p = this->section_reloc_map_.find(src_id); - if (p == this->section_reloc_map_.end()) - this->section_reloc_map_[src_id].insert(dst_id); - else - p->second.insert(dst_id); + Sections_reachable& reachable = this->section_reloc_map_[src_id]; + reachable.insert(dst_id); } private: @@ -157,12 +150,11 @@ struct Symbols_data template inline unsigned int -get_embedded_addend_size(int sh_type, int r_type, Relobj* obj) +get_embedded_addend_size(int r_type, Relobj* obj) { - if (sh_type != elfcpp::SHT_REL) - return 0; - Classify_reloc classify_reloc; - return classify_reloc.get_size_for_reloc(r_type, obj); + if (Classify_reloc::sh_type == elfcpp::SHT_REL) + return Classify_reloc::get_size_for_reloc(r_type, obj); + return 0; } // This function implements the generic part of reloc @@ -171,7 +163,7 @@ get_embedded_addend_size(int sh_type, int r_type, Relobj* obj) // garbage collection (--gc-sections) and identical code // folding (--icf). -template inline void gc_process_relocs( @@ -187,12 +179,10 @@ gc_process_relocs( size_t local_count, const unsigned char* plocal_syms) { - Object* dst_obj; - unsigned int dst_indx; Scan scan; - typedef typename Reloc_types::Reloc Reltype; - const int reloc_size = Reloc_types::reloc_size; + typedef typename Classify_reloc::Reltype Reltype; + const int reloc_size = Classify_reloc::reloc_size; const int sym_size = elfcpp::Elf_sizes::sym_size; Icf::Sections_reachable_info* secvec = NULL; @@ -210,7 +200,8 @@ gc_process_relocs( bool check_section_for_function_pointers = false; if (parameters->options().icf_enabled() - && is_section_foldable_candidate(src_section_name.c_str())) + && (is_section_foldable_candidate(src_section_name) + || is_prefix_of(".eh_frame", src_section_name.c_str()))) { is_icf_tracked = true; Section_id src_id(src_obj, src_indx); @@ -230,38 +221,47 @@ gc_process_relocs( for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size) { Reltype reloc(prelocs); - typename elfcpp::Elf_types::Elf_WXword r_info = reloc.get_r_info(); - unsigned int r_sym = elfcpp::elf_r_sym(r_info); - unsigned int r_type = elfcpp::elf_r_type(r_info); + unsigned int r_sym = Classify_reloc::get_r_sym(&reloc); + unsigned int r_type = Classify_reloc::get_r_type(&reloc); typename elfcpp::Elf_types::Elf_Swxword addend = - Reloc_types::get_reloc_addend_noerror(&reloc); + Classify_reloc::get_r_addend(&reloc); + Relobj* dst_obj; + unsigned int dst_indx; + 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() + addend; + if (is_icf_tracked) { + Address symvalue = dst_off - addend; if (is_ordinary) - (*secvec).push_back(Section_id(dst_obj, dst_indx)); + (*secvec).push_back(Section_id(src_obj, dst_indx)); 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))); + // If the target of the relocation is an STT_SECTION symbol, + // make a note of that by storing -1 in the symbol vector. + if (lsym.get_st_type() == elfcpp::STT_SECTION) + (*symvec).push_back(reinterpret_cast(-1)); + else + (*symvec).push_back(NULL); + (*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); (*reloc_addend_size_vec).push_back( - get_embedded_addend_size(sh_type, r_type, - src_obj)); + get_embedded_addend_size(r_type, src_obj)); } // When doing safe folding, check to see if this relocation is that @@ -269,14 +269,14 @@ gc_process_relocs( if (is_ordinary && check_section_for_function_pointers && lsym.get_st_type() != elfcpp::STT_OBJECT - && scan.local_reloc_may_be_function_pointer(symtab, NULL, NULL, + && scan.local_reloc_may_be_function_pointer(symtab, NULL, target, src_obj, src_indx, NULL, reloc, r_type, lsym)) 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 @@ -289,20 +289,24 @@ gc_process_relocs( dst_obj = NULL; dst_indx = 0; bool is_ordinary = false; - if (gsym->source() == Symbol::FROM_OBJECT) + if (gsym->source() == Symbol::FROM_OBJECT + && !gsym->object()->is_dynamic()) { - dst_obj = gsym->object(); + dst_obj = static_cast(gsym->object()); dst_indx = gsym->shndx(&is_ordinary); } + 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. if (gsym->source() == Symbol::FROM_OBJECT + && gsym->type() == elfcpp::STT_FUNC && check_section_for_function_pointers - && gsym->type() != elfcpp::STT_OBJECT + && dst_obj != NULL && (!is_ordinary || scan.global_reloc_may_be_function_pointer( - symtab, NULL, NULL, src_obj, src_indx, NULL, reloc, + symtab, NULL, target, src_obj, src_indx, NULL, reloc, r_type, gsym))) symtab->icf()->set_section_has_function_pointers(dst_obj, dst_indx); @@ -321,26 +325,23 @@ gc_process_relocs( } if (is_icf_tracked) { - if (is_ordinary && gsym->source() == Symbol::FROM_OBJECT) - (*secvec).push_back(Section_id(dst_obj, dst_indx)); + Address symvalue = dst_off - addend; + if (is_ordinary && dst_obj != NULL) + (*secvec).push_back(Section_id(dst_obj, dst_indx)); 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); (*reloc_addend_size_vec).push_back( - get_embedded_addend_size(sh_type, r_type, - src_obj)); + get_embedded_addend_size(r_type, src_obj)); } - if (gsym->source() != Symbol::FROM_OBJECT) + if (dst_obj == NULL) continue; if (!is_ordinary) continue; @@ -348,6 +349,9 @@ gc_process_relocs( if (parameters->options().gc_sections()) { symtab->gc()->add_reference(src_obj, src_indx, dst_obj, dst_indx); + parameters->sized_target() + ->gc_add_reference(symtab, src_obj, src_indx, dst_obj, dst_indx, + dst_off); if (cident_section_name != NULL) { Garbage_collection::Cident_section_map::iterator ele =