summaryrefslogtreecommitdiff
path: root/gold/gc.h
diff options
context:
space:
mode:
authorSriraman Tallam <tmsriram@google.com>2010-01-07 07:14:30 +0000
committerSriraman Tallam <tmsriram@google.com>2010-01-07 07:14:30 +0000
commitf1ec9ded5c740c22735843025e5d3a8ff4c4079e (patch)
tree107b73798abba65f1697fd2751cca3b6b31e9ef8 /gold/gc.h
parentb9674e179b86530631391dd38988d2f5da4f40c0 (diff)
* gc.h (Garbage_collection::Cident_section_map): New typedef.
(Garbage_collection::cident_sections): New function. (Garbage_collection::add_cident_section): New function. (Garbage_collection::cident_sections_): New member. (gc_process_relocs): Add references to sections whose names are C identifiers. * gold.h (cident_section_start_prefix): New constant. (cident_section_stop_prefix): New constant. (is_cident): New function. * layout.cc (Layout::define_section_symbols): Replace string constants with the newly defined constants. * object.cc (Sized_relobj::do_layout): Track sections whose names are C identifiers. * testsuite/Makefile.am: Add gc_orphan_section_test. * testsuite/Makefile.in: Regenerate. * testsuite/gc_orphan_section_test.cc: New file. * testsuite/gc_orphan_section_test.sh: New file.
Diffstat (limited to 'gold/gc.h')
-rw-r--r--gold/gc.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/gold/gc.h b/gold/gc.h
index f61a2f6813..838b7db48c 100644
--- a/gold/gc.h
+++ b/gold/gc.h
@@ -60,6 +60,10 @@ class Garbage_collection
typedef Unordered_set<Section_id, Section_id_hash> Sections_reachable;
typedef std::map<Section_id, Sections_reachable> Section_ref;
typedef std::queue<Section_id> 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.
+ typedef std::map<std::string, Sections_reachable> Cident_section_map;
Garbage_collection()
: is_worklist_ready_(false)
@@ -94,12 +98,23 @@ class Garbage_collection
is_section_garbage(Object* obj, unsigned int shndx)
{ return (this->referenced_list().find(Section_id(obj, shndx))
== this->referenced_list().end()); }
+
+ Cident_section_map*
+ cident_sections()
+ { return &cident_sections_; }
+
+ void
+ add_cident_section(std::string section_name,
+ Section_id secn)
+ { this->cident_sections_[section_name].insert(secn); }
+
private:
Worklist_type work_list_;
bool is_worklist_ready_;
Section_ref section_reloc_map_;
Sections_reachable referenced_list_;
+ Cident_section_map cident_sections_;
};
// Data to pass between successive invocations of do_layout
@@ -161,6 +176,7 @@ gc_process_relocs(
std::vector<Symbol*>* symvec = NULL;
std::vector<std::pair<long long, long long> >* addendvec = NULL;
bool is_icf_tracked = false;
+ const char* cident_section_name = NULL;
if (parameters->options().icf_enabled()
&& is_section_foldable_candidate(src_obj->section_name(src_indx).c_str()))
@@ -218,6 +234,19 @@ gc_process_relocs(
if (!is_ordinary)
continue;
Section_id dst_id(dst_obj, dst_indx);
+ // If the symbol name matches '__start_XXX' then the section with
+ // the C identifier like name 'XXX' should not be garbage collected.
+ // A similar treatment to symbols with the name '__stop_XXX'.
+ if (is_prefix_of(cident_section_start_prefix, gsym->name()))
+ {
+ cident_section_name = (gsym->name()
+ + strlen(cident_section_start_prefix));
+ }
+ else if (is_prefix_of(cident_section_stop_prefix, gsym->name()))
+ {
+ cident_section_name = (gsym->name()
+ + strlen(cident_section_stop_prefix));
+ }
if (is_icf_tracked)
{
(*secvec).push_back(dst_id);
@@ -245,6 +274,23 @@ gc_process_relocs(
Garbage_collection::Sections_reachable& v(map_it->second);
v.insert(dst_id);
}
+ if (cident_section_name != NULL)
+ {
+ Garbage_collection::Cident_section_map::iterator ele =
+ symtab->gc()->cident_sections()->find(std::string(cident_section_name));
+ if (ele == symtab->gc()->cident_sections()->end())
+ continue;
+ Garbage_collection::Sections_reachable&
+ v(symtab->gc()->section_reloc_map()[src_id]);
+ Garbage_collection::Sections_reachable& cident_secn(ele->second);
+ for (Garbage_collection::Sections_reachable::iterator it_v
+ = cident_secn.begin();
+ it_v != cident_secn.end();
+ ++it_v)
+ {
+ v.insert(*it_v);
+ }
+ }
}
}
return;