]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - bfd/elf-sframe.c
Fix the BFD library's find_nearest_line feature to produce consistent results.
[thirdparty/binutils-gdb.git] / bfd / elf-sframe.c
CommitLineData
cf0e0a0b 1/* .sframe section processing.
d87bef3a 2 Copyright (C) 2022-2023 Free Software Foundation, Inc.
cf0e0a0b
IB
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21#include "sysdep.h"
22#include "bfd.h"
23#include "libbfd.h"
24#include "elf-bfd.h"
25#include "sframe-api.h"
26
27/* Return TRUE if the function has been marked for deletion during the linking
28 process. */
29
30static bool
31sframe_decoder_func_deleted_p (struct sframe_dec_info *sfd_info,
32 unsigned int func_idx)
33{
34 if (func_idx < sfd_info->sfd_fde_count)
35 return sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p;
36
37 return false;
38}
39
40/* Mark the function in the decoder info for deletion. */
41
42static void
43sframe_decoder_mark_func_deleted (struct sframe_dec_info *sfd_info,
44 unsigned int func_idx)
45{
46 if (func_idx < sfd_info->sfd_fde_count)
47 sfd_info->sfd_func_bfdinfo[func_idx].func_deleted_p = true;
48}
49
50/* Get the relocation offset from the decoder info for the given function. */
51
52static unsigned int
53sframe_decoder_get_func_r_offset (struct sframe_dec_info *sfd_info,
54 unsigned int func_idx)
55{
56 BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
57 unsigned int func_r_offset
58 = sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset;
59 /* There must have been a reloc. */
60 BFD_ASSERT (func_r_offset);
61 return func_r_offset;
62}
63
64/* Bookkeep the function relocation offset in the decoder info. */
65
66static void
67sframe_decoder_set_func_r_offset (struct sframe_dec_info *sfd_info,
68 unsigned int func_idx,
69 unsigned int r_offset)
70{
71 if (func_idx < sfd_info->sfd_fde_count)
72 sfd_info->sfd_func_bfdinfo[func_idx].func_r_offset = r_offset;
73}
74
75/* Get the relocation index in the elf_reloc_cookie for the function. */
76
77static unsigned int
78sframe_decoder_get_func_reloc_index (struct sframe_dec_info *sfd_info,
79 unsigned int func_idx)
80{
81 BFD_ASSERT (func_idx < sfd_info->sfd_fde_count);
82 return sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index;
83}
84
85/* Bookkeep the relocation index in the elf_reloc_cookie for the function. */
86
87static void
88sframe_decoder_set_func_reloc_index (struct sframe_dec_info *sfd_info,
89 unsigned int func_idx,
90 unsigned int reloc_index)
91{
92 if (func_idx < sfd_info->sfd_fde_count)
93 sfd_info->sfd_func_bfdinfo[func_idx].func_reloc_index = reloc_index;
94}
95
96/* Initialize the set of additional information in CFD_INFO,
97 needed for linking SEC. Returns TRUE if setup is done successfully. */
98
99static bool
100sframe_decoder_init_func_bfdinfo (asection *sec,
101 struct sframe_dec_info *sfd_info,
102 struct elf_reloc_cookie *cookie)
103{
104 unsigned int fde_count;
105 unsigned int func_bfdinfo_size, i;
106
107 fde_count = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
108 sfd_info->sfd_fde_count = fde_count;
109
110 /* Allocate and clear the memory. */
111 func_bfdinfo_size = (sizeof (struct sframe_func_bfdinfo)) * fde_count;
112 sfd_info->sfd_func_bfdinfo
113 = (struct sframe_func_bfdinfo*) bfd_malloc (func_bfdinfo_size);
114 if (sfd_info->sfd_func_bfdinfo == NULL)
115 return false;
116 memset (sfd_info->sfd_func_bfdinfo, 0, func_bfdinfo_size);
117
118 /* For linker generated .sframe sections, we have no relocs. Skip. */
119 if ((sec->flags & SEC_LINKER_CREATED) && cookie->rels == NULL)
120 return true;
121
122 for (i = 0; i < fde_count; i++)
123 {
124 cookie->rel = cookie->rels + i;
125 BFD_ASSERT (cookie->rel < cookie->relend);
126 /* Bookkeep the relocation offset and relocation index of each function
127 for later use. */
128 sframe_decoder_set_func_r_offset (sfd_info, i, cookie->rel->r_offset);
129 sframe_decoder_set_func_reloc_index (sfd_info, i,
130 (cookie->rel - cookie->rels));
131
132 cookie->rel++;
133 }
134 BFD_ASSERT (cookie->rel == cookie->relend);
135
136 return true;
137}
138
139/* Read the value from CONTENTS at the specified OFFSET for the given ABFD. */
140
141static bfd_vma
142sframe_read_value (bfd *abfd, bfd_byte *contents, unsigned int offset,
143 unsigned int width)
144{
145 BFD_ASSERT (contents && offset);
146 /* Supporting the usecase of reading only the 4-byte relocated
147 value (signed offset for func start addr) for now. */
148 BFD_ASSERT (width == 4);
149 /* FIXME endianness ?? */
150 unsigned char *buf = contents + offset;
151 bfd_vma value = bfd_get_signed_32 (abfd, buf);
152 return value;
153}
154
155/* Return true if there is at least one non-empty .sframe section in
156 input files. Can only be called after ld has mapped input to
157 output sections, and before sections are stripped. */
158
159bool
160_bfd_elf_sframe_present (struct bfd_link_info *info)
161{
162 asection *sframe = bfd_get_section_by_name (info->output_bfd, ".sframe");
163
164 if (sframe == NULL)
165 return false;
166
167 /* Count only sections which have at least a single FDE. */
168 for (sframe = sframe->map_head.s; sframe != NULL; sframe = sframe->map_head.s)
169 /* Note that this may become an approximate check in the future when
170 some ABI/arch begin to use the sfh_auxhdr_len. When sfh_auxhdr_len has
171 non-zero value, it will need to be accounted for in the calculation of
172 the SFrame header size. */
173 if (sframe->size > sizeof (sframe_header))
174 return true;
175 return false;
176}
177
178/* Try to parse .sframe section SEC, which belongs to ABFD. Store the
179 information in the section's sec_info field on success. COOKIE
180 describes the relocations in SEC.
181
182 Returns TRUE if success, FALSE if any error or failure. */
183
184bool
185_bfd_elf_parse_sframe (bfd *abfd,
186 struct bfd_link_info *info ATTRIBUTE_UNUSED,
187 asection *sec, struct elf_reloc_cookie *cookie)
188{
189 bfd_byte *sfbuf = NULL;
190 struct sframe_dec_info *sfd_info;
191 sframe_decoder_ctx *sfd_ctx;
192 bfd_size_type sf_size;
193 int decerr = 0;
194
195 if (sec->size == 0
81ff113f 196 || (sec->flags & SEC_HAS_CONTENTS) == 0
cf0e0a0b
IB
197 || sec->sec_info_type != SEC_INFO_TYPE_NONE)
198 {
199 /* This file does not contain .sframe information. */
200 return false;
201 }
202
203 if (bfd_is_abs_section (sec->output_section))
204 {
205 /* At least one of the sections is being discarded from the
206 link, so we should just ignore them. */
207 return false;
208 }
209
53d8d3f0 210 /* Read the SFrame stack trace information from abfd. */
cf0e0a0b
IB
211 if (!bfd_malloc_and_get_section (abfd, sec, &sfbuf))
212 goto fail_no_free;
213
214 /* Decode the buffer and keep decoded contents for later use.
215 Relocations are performed later, but are such that the section's
216 size is unaffected. */
217 sfd_info = bfd_malloc (sizeof (struct sframe_dec_info));
218 sf_size = sec->size;
219
220 sfd_info->sfd_ctx = sframe_decode ((const char*)sfbuf, sf_size, &decerr);
221 sfd_ctx = sfd_info->sfd_ctx;
222 if (!sfd_ctx)
223 /* Free'ing up any memory held by decoder context is done by
224 sframe_decode in case of error. */
225 goto fail_no_free;
226
227 if (!sframe_decoder_init_func_bfdinfo (sec, sfd_info, cookie))
228 {
229 sframe_decoder_free (&sfd_ctx);
230 goto fail_no_free;
231 }
232
233 elf_section_data (sec)->sec_info = sfd_info;
234 sec->sec_info_type = SEC_INFO_TYPE_SFRAME;
235
236 goto success;
237
238fail_no_free:
239 _bfd_error_handler
240 (_("error in %pB(%pA); no .sframe will be created"),
241 abfd, sec);
242 return false;
243success:
244 free (sfbuf);
245 return true;
246}
247
248/* This function is called for each input file before the .sframe section
249 is relocated. It marks the SFrame FDE for the discarded functions for
250 deletion.
251
252 The function returns TRUE iff any entries have been deleted. */
253
254bool
255_bfd_elf_discard_section_sframe
256 (asection *sec,
257 bool (*reloc_symbol_deleted_p) (bfd_vma, void *),
258 struct elf_reloc_cookie *cookie)
259{
260 bool changed;
261 bool keep;
262 unsigned int i;
263 unsigned int func_desc_offset;
264 unsigned int num_fidx;
265 struct sframe_dec_info *sfd_info;
266
267 changed = false;
268 /* FIXME - if relocatable link and changed = true, how does the final
269 .rela.sframe get updated ?. */
270 keep = false;
271
272 sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
273
274 /* Skip checking for the linker created .sframe sections
275 (for PLT sections). */
276 if ((sec->flags & SEC_LINKER_CREATED) == 0 || cookie->rels != NULL)
277 {
278 num_fidx = sframe_decoder_get_num_fidx (sfd_info->sfd_ctx);
279 for (i = 0; i < num_fidx; i++)
280 {
281 func_desc_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
282
283 cookie->rel = cookie->rels
284 + sframe_decoder_get_func_reloc_index (sfd_info, i);
285 keep = !(*reloc_symbol_deleted_p) (func_desc_offset, cookie);
286
287 if (!keep)
288 {
289 sframe_decoder_mark_func_deleted (sfd_info, i);
290 changed = true;
291 }
292 }
293 }
294 return changed;
295}
296
297/* Update the reference to the output .sframe section in the output ELF
298 BFD ABFD. Returns true if no error. */
299
300bool
301_bfd_elf_set_section_sframe (bfd *abfd,
302 struct bfd_link_info *info)
303{
304 asection *cfsec;
305
306 cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
307 if (!cfsec)
308 return false;
309
310 elf_sframe (abfd) = cfsec;
311
312 return true;
313}
314
315/* Merge .sframe section SEC. This is called with the relocated
316 CONTENTS. */
317
318bool
319_bfd_elf_merge_section_sframe (bfd *abfd,
320 struct bfd_link_info *info,
321 asection *sec,
322 bfd_byte *contents)
323{
324 struct sframe_dec_info *sfd_info;
325 struct sframe_enc_info *sfe_info;
326 sframe_decoder_ctx *sfd_ctx;
327 sframe_encoder_ctx *sfe_ctx;
328 unsigned char sfd_ctx_abi_arch;
329 int8_t sfd_ctx_fixed_fp_offset;
330 int8_t sfd_ctx_fixed_ra_offset;
331 int encerr = 0;
332
333 struct elf_link_hash_table *htab;
334 asection *cfsec;
335
336 /* Sanity check - handle SFrame sections only. */
337 if (sec->sec_info_type != SEC_INFO_TYPE_SFRAME)
338 return false;
339
340 sfd_info = (struct sframe_dec_info *) elf_section_data (sec)->sec_info;
341 sfd_ctx = sfd_info->sfd_ctx;
342
343 htab = elf_hash_table (info);
344 sfe_info = &(htab->sfe_info);
345 sfe_ctx = sfe_info->sfe_ctx;
346
347 /* All input bfds are expected to have a valid SFrame section. Even if
348 the SFrame section is empty with only a header, there must be a valid
349 SFrame decoder context by now. The SFrame encoder context, however,
350 will get set later here, if this is the first call to the function. */
351 if (sfd_ctx == NULL || sfe_info == NULL)
352 return false;
353
354 if (htab->sfe_info.sfe_ctx == NULL)
355 {
356 sfd_ctx_abi_arch = sframe_decoder_get_abi_arch (sfd_ctx);
357 sfd_ctx_fixed_fp_offset = sframe_decoder_get_fixed_fp_offset (sfd_ctx);
358 sfd_ctx_fixed_ra_offset = sframe_decoder_get_fixed_ra_offset (sfd_ctx);
359
360 /* Valid values are non-zero. */
361 if (!sfd_ctx_abi_arch)
362 return false;
363
364 htab->sfe_info.sfe_ctx = sframe_encode (SFRAME_VERSION_1,
365 0, /* SFrame flags. */
366 sfd_ctx_abi_arch,
367 sfd_ctx_fixed_fp_offset,
368 sfd_ctx_fixed_ra_offset,
369 &encerr);
370 /* Handle errors from sframe_encode. */
371 if (htab->sfe_info.sfe_ctx == NULL)
372 return false;
373 }
374 sfe_ctx = sfe_info->sfe_ctx;
375
376 if (sfe_info->sframe_section == NULL)
377 {
378 /* Make sure things are set for an eventual write.
379 Size of the output section is not known until
380 _bfd_elf_write_section_sframe is ready with the buffer
381 to write out. */
382 cfsec = bfd_get_section_by_name (info->output_bfd, ".sframe");
383 if (cfsec)
384 {
385 sfe_info->sframe_section = cfsec;
386 // elf_sframe (abfd) = cfsec;
387 }
388 else
389 return false;
390 }
391
392 /* Check that all .sframe sections being linked have the same
393 ABI/arch. */
394 if (sframe_decoder_get_abi_arch (sfd_ctx)
395 != sframe_encoder_get_abi_arch (sfe_ctx))
396 {
397 _bfd_error_handler
398 (_("input SFrame sections with different abi prevent .sframe"
399 " generation"));
400 return false;
401 }
402
403 /* Iterate over the function descriptor entries and the FREs of the
404 function from the decoder context. Add each of them to the encoder
405 context, if suitable. */
406 unsigned int i = 0, j = 0, cur_fidx = 0;
407
408 unsigned int num_fidx = sframe_decoder_get_num_fidx (sfd_ctx);
409 unsigned int num_enc_fidx = sframe_encoder_get_num_fidx (sfe_ctx);
410
411 for (i = 0; i < num_fidx; i++)
412 {
413 unsigned int num_fres = 0;
414 int32_t func_start_address;
415 bfd_vma address;
416 uint32_t func_size = 0;
417 unsigned char func_info = 0;
418 unsigned int r_offset = 0;
419 bool pltn_reloc_by_hand = false;
420 unsigned int pltn_r_offset = 0;
421
422 if (!sframe_decoder_get_funcdesc (sfd_ctx, i, &num_fres, &func_size,
423 &func_start_address, &func_info))
424 {
425 /* If function belongs to a deleted section, skip editing the
426 function descriptor entry. */
427 if (sframe_decoder_func_deleted_p(sfd_info, i))
428 continue;
429
430 /* Don't edit function descriptor entries for relocatable link. */
431 if (!bfd_link_relocatable (info))
432 {
433 if (!(sec->flags & SEC_LINKER_CREATED))
434 {
435 /* Get relocated contents by reading the value of the
436 relocated function start address at the beginning of the
437 function descriptor entry. */
438 r_offset = sframe_decoder_get_func_r_offset (sfd_info, i);
439 }
440 else
441 {
53d8d3f0
IB
442 /* Expected to land here when SFrame stack trace info is
443 created dynamically for the .plt* sections. These
444 sections are expected to have upto two SFrame FDE entries.
445 Although the code should work for > 2, leaving this
446 assert here for safety. */
cf0e0a0b
IB
447 BFD_ASSERT (num_fidx <= 2);
448 /* For the first entry, we know the offset of the SFrame FDE's
449 sfde_func_start_address. Side note: see how the value
450 of PLT_SFRAME_FDE_START_OFFSET is also set to the
451 same. */
452 r_offset = sframe_decoder_get_hdr_size (sfd_ctx);
453 /* For any further SFrame FDEs, the generator has already put
454 in an offset in place of sfde_func_start_address of the
455 corresponding FDE. We will use it by hand to relocate. */
456 if (i > 0)
457 {
458 pltn_r_offset
459 = r_offset + (i * sizeof (sframe_func_desc_entry));
460 pltn_reloc_by_hand = true;
461 }
462 }
463
464 /* Get the SFrame FDE function start address after relocation. */
465 address = sframe_read_value (abfd, contents, r_offset, 4);
466 if (pltn_reloc_by_hand)
467 address += sframe_read_value (abfd, contents,
468 pltn_r_offset, 4);
469 address += (sec->output_offset + r_offset);
470
471 /* FIXME For testing only. Cleanup later. */
472 // address += (sec->output_section->vma);
473
474 func_start_address = address;
475 }
476
477 /* Update the encoder context with updated content. */
478 int err = sframe_encoder_add_funcdesc (sfe_ctx, func_start_address,
479 func_size, func_info,
480 num_fres);
481 cur_fidx++;
482 BFD_ASSERT (!err);
483 }
484
485 for (j = 0; j < num_fres; j++)
486 {
487 sframe_frame_row_entry fre;
488 if (!sframe_decoder_get_fre (sfd_ctx, i, j, &fre))
489 {
490 int err = sframe_encoder_add_fre (sfe_ctx,
491 cur_fidx-1+num_enc_fidx,
492 &fre);
493 BFD_ASSERT (!err);
494 }
495 }
496 }
497 /* Free the SFrame decoder context. */
498 sframe_decoder_free (&sfd_ctx);
499
500 return true;
501}
502
503/* Write out the .sframe section. This must be called after
504 _bfd_elf_merge_section_sframe has been called on all input
505 .sframe sections. */
506
507bool
508_bfd_elf_write_section_sframe (bfd *abfd, struct bfd_link_info *info)
509{
510 bool retval = true;
511
512 struct elf_link_hash_table *htab;
513 struct sframe_enc_info *sfe_info;
514 sframe_encoder_ctx *sfe_ctx;
515 asection *sec;
516 void *contents;
517 size_t sec_size;
518 int err = 0;
519
520 htab = elf_hash_table (info);
521 sfe_info = &htab->sfe_info;
522 sec = sfe_info->sframe_section;
523 sfe_ctx = sfe_info->sfe_ctx;
524
525 if (sec == NULL)
526 return true;
527
528 contents = sframe_encoder_write (sfe_ctx, &sec_size, &err);
529 sec->size = (bfd_size_type) sec_size;
530
531 if (!bfd_set_section_contents (abfd, sec->output_section, contents,
532 (file_ptr) sec->output_offset,
533 sec->size))
534 retval = false;
535 else if (!bfd_link_relocatable (info))
536 {
537 Elf_Internal_Shdr *hdr = &elf_section_data (sec)->this_hdr;
538 hdr->sh_size = sec->size;
539 }
540 /* For relocatable links, do not update the section size as the section
541 contents have not been relocated. */
542
543 sframe_encoder_free (&sfe_ctx);
544
545 return retval;
546}