* section.c (bfd_get_section_contents): Detect and handle the case
[binutils.git] / gold / gc.h
blobb7d520f258996d0b4a981ffb9eacd6cc0a7173bd
1 // gc.h -- garbage collection of unused sections
3 // Copyright 2009 Free Software Foundation, Inc.
4 // Written by Sriraman Tallam <tmsriram@google.com>.
6 // This file is part of gold.
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 // MA 02110-1301, USA.
23 #ifndef GOLD_GC_H
24 #define GOLD_GC_H
26 #include <queue>
28 #include "elfcpp.h"
29 #include "symtab.h"
31 namespace gold
34 class Object;
36 template<int size, bool big_endian>
37 class Sized_relobj;
39 template<int sh_type, int size, bool big_endian>
40 class Reloc_types;
42 class Output_section;
43 class General_options;
44 class Layout;
46 typedef std::pair<Object *, unsigned int> Section_id;
48 class Garbage_collection
50 struct Section_id_hash
52 size_t operator()(const Section_id& loc) const
53 { return reinterpret_cast<uintptr_t>(loc.first) ^ loc.second; }
56 typedef Unordered_set<Section_id, Section_id_hash> Sections_reachable;
57 typedef std::map<Section_id, Sections_reachable> Section_ref;
58 typedef std::queue<Section_id> Worklist_type;
60 public :
61 Garbage_collection()
62 :is_worklist_ready_(false)
63 { }
65 // Accessor methods for the private members.
67 Sections_reachable&
68 referenced_list()
69 { return referenced_list_; }
71 Section_ref&
72 section_reloc_map()
73 { return section_reloc_map_; }
75 Worklist_type&
76 worklist()
77 { return work_list_; }
79 bool
80 is_worklist_ready()
81 { return is_worklist_ready_; }
83 void
84 worklist_ready()
85 { is_worklist_ready_ = true; }
87 void
88 do_transitive_closure();
90 private :
91 Worklist_type work_list_;
92 bool is_worklist_ready_;
93 Section_ref section_reloc_map_;
94 Sections_reachable referenced_list_;
97 // Data to pass between successive invocations of do_layout
98 // in object.cc while garbage collecting. This data structure
99 // is filled by using the data from Read_symbols_data.
101 struct Symbols_data
103 // Section headers.
104 unsigned char* section_headers_data;
105 // Section names.
106 unsigned char* section_names_data;
107 // Size of section name data in bytes.
108 section_size_type section_names_size;
109 // Symbol data.
110 unsigned char* symbols_data;
111 // Size of symbol data in bytes.
112 section_size_type symbols_size;
113 // Offset of external symbols within symbol data. This structure
114 // sometimes contains only external symbols, in which case this will
115 // be zero. Sometimes it contains all symbols.
116 section_offset_type external_symbols_offset;
117 // Symbol names.
118 unsigned char* symbol_names_data;
119 // Size of symbol name data in bytes.
120 section_size_type symbol_names_size;
123 // This function implements the the generic part of reloc
124 // processing to map a section to all the sections it
125 // references through relocs. It is used only during garbage
126 // collection.
128 template<int size, bool big_endian, typename Target_type, int sh_type,
129 typename Scan>
130 inline void
131 gc_process_relocs(
132 const General_options& ,
133 Symbol_table* symtab,
134 Layout*,
135 Target_type* ,
136 Sized_relobj<size, big_endian>* object,
137 unsigned int data_shndx,
138 const unsigned char* prelocs,
139 size_t reloc_count,
140 Output_section*,
141 bool ,
142 size_t local_count,
143 const unsigned char* plocal_syms)
145 Object *src_obj, *dst_obj;
146 unsigned int src_indx, dst_indx;
148 src_obj = object;
149 src_indx = data_shndx;
151 typedef typename Reloc_types<sh_type, size, big_endian>::Reloc Reltype;
152 const int reloc_size = Reloc_types<sh_type, size, big_endian>::reloc_size;
153 const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
155 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
157 Reltype reloc(prelocs);
158 typename elfcpp::Elf_types<size>::Elf_WXword r_info = reloc.get_r_info();
159 unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
161 if (r_sym < local_count)
163 gold_assert(plocal_syms != NULL);
164 typename elfcpp::Sym<size, big_endian> lsym(plocal_syms
165 + r_sym * sym_size);
166 unsigned int shndx = lsym.get_st_shndx();
167 bool is_ordinary;
168 shndx = object->adjust_sym_shndx(r_sym, shndx, &is_ordinary);
169 if (!is_ordinary)
170 continue;
171 dst_obj = src_obj;
172 if (shndx == src_indx)
173 continue;
174 dst_indx = shndx;
176 else
178 Symbol* gsym = object->global_symbol(r_sym);
179 gold_assert(gsym != NULL);
180 if (gsym->is_forwarder())
181 gsym = symtab->resolve_forwards(gsym);
182 if (gsym->source() != Symbol::FROM_OBJECT)
183 continue;
184 bool is_ordinary;
185 dst_obj = gsym->object();
186 dst_indx = gsym->shndx(&is_ordinary);
187 if (!is_ordinary)
188 continue;
190 Section_id p1(src_obj, src_indx);
191 Section_id p2(dst_obj, dst_indx);
192 Garbage_collection::Section_ref::iterator map_it;
193 map_it = symtab->gc()->section_reloc_map().find(p1);
194 if (map_it == symtab->gc()->section_reloc_map().end())
196 symtab->gc()->section_reloc_map()[p1].insert(p2);
198 else
200 Garbage_collection::Sections_reachable& v(map_it->second);
201 v.insert(p2);
204 return;
207 } // End of namespace gold.
209 #endif