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.
36 template<int size
, bool big_endian
>
39 template<int sh_type
, int size
, bool big_endian
>
43 class General_options
;
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
;
62 :is_worklist_ready_(false)
65 // Accessor methods for the private members.
69 { return referenced_list_
; }
73 { return section_reloc_map_
; }
77 { return work_list_
; }
81 { return is_worklist_ready_
; }
85 { is_worklist_ready_
= true; }
88 do_transitive_closure();
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.
104 unsigned char* section_headers_data
;
106 unsigned char* section_names_data
;
107 // Size of section name data in bytes.
108 section_size_type section_names_size
;
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
;
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
128 template<int size
, bool big_endian
, typename Target_type
, int sh_type
,
132 const General_options
& ,
133 Symbol_table
* symtab
,
136 Sized_relobj
<size
, big_endian
>* object
,
137 unsigned int data_shndx
,
138 const unsigned char* prelocs
,
143 const unsigned char* plocal_syms
)
145 Object
*src_obj
, *dst_obj
;
146 unsigned int src_indx
, dst_indx
;
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
166 unsigned int shndx
= lsym
.get_st_shndx();
168 shndx
= object
->adjust_sym_shndx(r_sym
, shndx
, &is_ordinary
);
172 if (shndx
== src_indx
)
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
)
185 dst_obj
= gsym
->object();
186 dst_indx
= gsym
->shndx(&is_ordinary
);
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
);
200 Garbage_collection::Sections_reachable
& v(map_it
->second
);
207 } // End of namespace gold.