2009-01-20 Sriraman Tallam <tmsriram@google.com>
[deliverable/binutils-gdb.git] / gold / gc.h
CommitLineData
6d03d481
ST
1// gc.h -- garbage collection of unused sections
2
3// Copyright 2009 Free Software Foundation, Inc.
4// Written by Sriraman Tallam <tmsriram@google.com>.
5
6// This file is part of gold.
7
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.
12
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.
17
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.
22
23#ifndef GOLD_GC_H
24#define GOLD_GC_H
25
26#include <queue>
27
28#include "elfcpp.h"
29#include "symtab.h"
30
31namespace gold
32{
33
34class Object;
35
36template<int size, bool big_endian>
37class Sized_relobj;
38
39template<int sh_type, int size, bool big_endian>
40class Reloc_types;
41
42class Output_section;
43class General_options;
44class Layout;
45
46typedef std::pair<Object *, unsigned int> Section_id;
47
48class Garbage_collection
49{
50 struct Section_id_hash
51 {
52 size_t operator()(const Section_id& loc) const
53 { return reinterpret_cast<uintptr_t>(loc.first) ^ loc.second; }
54 };
55
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;
59
60 public :
61 Garbage_collection()
62 :is_worklist_ready_(false)
63 { }
64
65 // Accessor methods for the private members.
66
67 Sections_reachable&
68 referenced_list()
69 { return referenced_list_; }
70
71 Section_ref&
72 section_reloc_map()
73 { return section_reloc_map_; }
74
75 Worklist_type&
76 worklist()
77 { return work_list_; }
78
79 bool
80 is_worklist_ready()
81 { return is_worklist_ready_; }
82
83 void
84 worklist_ready()
85 { is_worklist_ready_ = true; }
86
87 void
88 do_transitive_closure();
89
90 private :
91 Worklist_type work_list_;
92 bool is_worklist_ready_;
93 Section_ref section_reloc_map_;
94 Sections_reachable referenced_list_;
95};
96
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.
100
101struct Symbols_data
102{
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;
121};
122
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.
127
128template<int size, bool big_endian, typename Target_type, int sh_type,
129 typename Scan>
130inline void
131gc_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)
144{
145 Object *src_obj, *dst_obj;
146 unsigned int src_indx, dst_indx;
147
148 src_obj = object;
149 src_indx = data_shndx;
150
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;
154
155 for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
156 {
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);
160
161 if (r_sym < local_count)
162 {
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;
175 }
176 else
177 {
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;
189 }
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())
195 {
196 symtab->gc()->section_reloc_map()[p1].insert(p2);
197 }
198 else
199 {
200 Garbage_collection::Sections_reachable& v(map_it->second);
201 v.insert(p2);
202 }
203 }
204 return;
205}
206
207} // End of namespace gold.
208
209#endif
This page took 0.045814 seconds and 4 git commands to generate.