1 // reloc.cc -- relocate input files for gold.
13 // Relocate_task methods.
15 // These tasks are always runnable.
17 Task::Is_runnable_type
18 Relocate_task::is_runnable(Workqueue
*)
23 // We want to lock the file while we run. We want to unblock
24 // FINAL_BLOCKER when we are done.
26 class Relocate_task::Relocate_locker
: public Task_locker
29 Relocate_locker(Task_token
& token
, Workqueue
* workqueue
,
31 : blocker_(token
, workqueue
), objlock_(*object
)
35 Task_locker_block blocker_
;
36 Task_locker_obj
<Object
> objlock_
;
40 Relocate_task::locks(Workqueue
* workqueue
)
42 return new Relocate_locker(*this->final_blocker_
, workqueue
,
49 Relocate_task::run(Workqueue
*)
51 this->object_
->relocate(this->options_
, this->symtab_
, this->sympool_
,
55 // Relocate the input sections and write out the local symbols.
57 template<int size
, bool big_endian
>
59 Sized_object
<size
, big_endian
>::do_relocate(const General_options
&,
60 const Symbol_table
* symtab
,
61 const Stringpool
* sympool
,
64 unsigned int shnum
= this->shnum();
66 // Read the section headers.
67 const unsigned char* pshdrs
= this->get_view(this->shoff_
,
68 shnum
* This::shdr_size
);
73 // Make two passes over the sections. The first one copies the
74 // section data to the output file. The second one applies
77 this->write_sections(pshdrs
, of
, &views
);
81 this->relocate_sections(symtab
, pshdrs
, &views
);
83 // Write out the accumulated views.
84 for (unsigned int i
= 1; i
< shnum
; ++i
)
86 if (views
[i
].view
!= NULL
)
87 of
->write_output_view(views
[i
].offset
, views
[i
].view_size
,
91 // Write out the local symbols.
92 this->write_local_symbols(of
, sympool
);
95 // Write section data to the output file. PSHDRS points to the
96 // section headers. Record the views in *PVIEWS for use when
99 template<int size
, bool big_endian
>
101 Sized_object
<size
, big_endian
>::write_sections(const unsigned char* pshdrs
,
105 unsigned int shnum
= this->shnum();
106 std::vector
<Map_to_output
>& map_sections(this->map_to_output());
108 const unsigned char* p
= pshdrs
+ This::shdr_size
;
109 for (unsigned int i
= 1; i
< shnum
; ++i
, p
+= This::shdr_size
)
111 View_size
* pvs
= &(*pviews
)[i
];
115 const Output_section
* os
= map_sections
[i
].output_section
;
119 typename
This::Shdr
shdr(p
);
121 if (shdr
.get_sh_type() == elfcpp::SHT_NOBITS
)
124 assert(map_sections
[i
].offset
>= 0
125 && map_sections
[i
].offset
< os
->data_size());
126 off_t start
= os
->offset() + map_sections
[i
].offset
;
127 off_t sh_size
= shdr
.get_sh_size();
129 unsigned char* view
= of
->get_output_view(start
, sh_size
);
130 this->input_file()->file().read(shdr
.get_sh_offset(),
134 pvs
->address
= os
->address() + map_sections
[i
].offset
;
136 pvs
->view_size
= sh_size
;
140 // Relocate section data. VIEWS points to the section data as views
141 // in the output file.
143 template<int size
, bool big_endian
>
145 Sized_object
<size
, big_endian
>::relocate_sections(const Symbol_table
* symtab
,
146 const unsigned char* pshdrs
,
149 unsigned int shnum
= this->shnum();
150 std::vector
<Map_to_output
>& map_sections(this->map_to_output());
151 Sized_target
<size
, big_endian
>* target
= this->sized_target();
153 const unsigned char* p
= pshdrs
+ This::shdr_size
;
154 for (unsigned int i
= 1; i
< shnum
; ++i
, p
+= This::shdr_size
)
156 typename
This::Shdr
shdr(p
);
158 unsigned int sh_type
= shdr
.get_sh_type();
159 if (sh_type
!= elfcpp::SHT_REL
&& sh_type
!= elfcpp::SHT_RELA
)
162 unsigned int index
= shdr
.get_sh_info();
163 if (index
>= this->shnum())
165 fprintf(stderr
, _("%s: %s: relocation section %u has bad info %u\n"),
166 program_name
, this->name().c_str(), i
, index
);
170 if (map_sections
[index
].output_section
== NULL
)
172 // This relocation section is against a section which we
177 assert((*pviews
)[index
].view
!= NULL
);
179 if (shdr
.get_sh_link() != this->symtab_shnum_
)
182 _("%s: %s: relocation section %u uses unexpected "
183 "symbol table %u\n"),
184 program_name
, this->name().c_str(), i
, shdr
.get_sh_link());
188 off_t sh_size
= shdr
.get_sh_size();
189 const unsigned char* prelocs
= this->get_view(shdr
.get_sh_offset(),
192 unsigned int reloc_size
;
193 if (sh_type
== elfcpp::SHT_REL
)
194 reloc_size
= elfcpp::Elf_sizes
<size
>::rel_size
;
196 reloc_size
= elfcpp::Elf_sizes
<size
>::rela_size
;
198 if (reloc_size
!= shdr
.get_sh_entsize())
201 _("%s: %s: unexpected entsize for reloc section %u: "
203 program_name
, this->name().c_str(), i
,
204 static_cast<unsigned long>(shdr
.get_sh_entsize()),
209 size_t reloc_count
= sh_size
/ reloc_size
;
210 if (reloc_count
* reloc_size
!= sh_size
)
212 fprintf(stderr
, _("%s: %s: reloc section %u size %lu uneven"),
213 program_name
, this->name().c_str(), i
,
214 static_cast<unsigned long>(sh_size
));
218 target
->relocate_section(symtab
, this, sh_type
, prelocs
, reloc_count
,
219 this->local_symbol_count_
,
222 (*pviews
)[index
].view
,
223 (*pviews
)[index
].address
,
224 (*pviews
)[index
].view_size
);
228 // Instantiate the templates we need. We could use the configure
229 // script to restrict this to only the ones for implemented targets.
233 Sized_object
<32, false>::do_relocate(const General_options
& options
,
234 const Symbol_table
* symtab
,
235 const Stringpool
* sympool
,
240 Sized_object
<32, true>::do_relocate(const General_options
& options
,
241 const Symbol_table
* symtab
,
242 const Stringpool
* sympool
,
247 Sized_object
<64, false>::do_relocate(const General_options
& options
,
248 const Symbol_table
* symtab
,
249 const Stringpool
* sympool
,
254 Sized_object
<64, true>::do_relocate(const General_options
& options
,
255 const Symbol_table
* symtab
,
256 const Stringpool
* sympool
,
260 } // End namespace gold.