Automatic date update in version.in
[deliverable/binutils-gdb.git] / bfd / elf64-bpf.c
1 /* Linux bpf specific support for 64-bit ELF
2 Copyright (C) 2019-2020 Free Software Foundation, Inc.
3 Contributed by Oracle Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
21
22 #include "sysdep.h"
23 #include "bfd.h"
24 #include "libbfd.h"
25 #include "elf-bfd.h"
26 #include "elf/bpf.h"
27 #include "libiberty.h"
28
29 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
30 #define MINUS_ONE (~ (bfd_vma) 0)
31
32 #define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset)
33
34 static bfd_reloc_status_type bpf_elf_generic_reloc
35 (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
36
37 /* Relocation tables. */
38 static reloc_howto_type bpf_elf_howto_table [] =
39 {
40 /* This reloc does nothing. */
41 HOWTO (R_BPF_NONE, /* type */
42 0, /* rightshift */
43 3, /* size (0 = byte, 1 = short, 2 = long) */
44 0, /* bitsize */
45 FALSE, /* pc_relative */
46 0, /* bitpos */
47 complain_overflow_dont, /* complain_on_overflow */
48 bpf_elf_generic_reloc, /* special_function */
49 "R_BPF_NONE", /* name */
50 FALSE, /* partial_inplace */
51 0, /* src_mask */
52 0, /* dst_mask */
53 FALSE), /* pcrel_offset */
54
55 /* 64-immediate in LDDW instruction. */
56 HOWTO (R_BPF_INSN_64, /* type */
57 0, /* rightshift */
58 4, /* size (0 = byte, 1 = short, 2 = long) */
59 64, /* bitsize */
60 FALSE, /* pc_relative */
61 32, /* bitpos */
62 complain_overflow_signed, /* complain_on_overflow */
63 bpf_elf_generic_reloc, /* special_function */
64 "R_BPF_INSN_64", /* name */
65 TRUE, /* partial_inplace */
66 MINUS_ONE, /* src_mask */
67 MINUS_ONE, /* dst_mask */
68 TRUE), /* pcrel_offset */
69
70 /* 32-immediate in many instructions. */
71 HOWTO (R_BPF_INSN_32, /* type */
72 0, /* rightshift */
73 2, /* size (0 = byte, 1 = short, 2 = long) */
74 32, /* bitsize */
75 FALSE, /* pc_relative */
76 32, /* bitpos */
77 complain_overflow_signed, /* complain_on_overflow */
78 bpf_elf_generic_reloc, /* special_function */
79 "R_BPF_INSN_32", /* name */
80 TRUE, /* partial_inplace */
81 0xffffffff, /* src_mask */
82 0xffffffff, /* dst_mask */
83 TRUE), /* pcrel_offset */
84
85 /* 16-bit offsets in instructions. */
86 HOWTO (R_BPF_INSN_16, /* type */
87 0, /* rightshift */
88 1, /* size (0 = byte, 1 = short, 2 = long) */
89 16, /* bitsize */
90 FALSE, /* pc_relative */
91 16, /* bitpos */
92 complain_overflow_signed, /* complain_on_overflow */
93 bpf_elf_generic_reloc, /* special_function */
94 "R_BPF_INSN_16", /* name */
95 TRUE, /* partial_inplace */
96 0x0000ffff, /* src_mask */
97 0x0000ffff, /* dst_mask */
98 TRUE), /* pcrel_offset */
99
100 /* 16-bit PC-relative address in jump instructions. */
101 HOWTO (R_BPF_INSN_DISP16, /* type */
102 0, /* rightshift */
103 1, /* size (0 = byte, 1 = short, 2 = long) */
104 16, /* bitsize */
105 TRUE, /* pc_relative */
106 16, /* bitpos */
107 complain_overflow_signed, /* complain_on_overflow */
108 bpf_elf_generic_reloc, /* special_function */
109 "R_BPF_INSN_DISP16", /* name */
110 TRUE, /* partial_inplace */
111 0xffff, /* src_mask */
112 0xffff, /* dst_mask */
113 TRUE), /* pcrel_offset */
114
115 HOWTO (R_BPF_DATA_8_PCREL,
116 0, /* rightshift */
117 0, /* size (0 = byte, 1 = short, 2 = long) */
118 8, /* bitsize */
119 TRUE, /* pc_relative */
120 0, /* bitpos */
121 complain_overflow_signed, /* complain_on_overflow */
122 bpf_elf_generic_reloc, /* special_function */
123 "R_BPF_8_PCREL", /* name */
124 TRUE, /* partial_inplace */
125 0xff, /* src_mask */
126 0xff, /* dst_mask */
127 TRUE), /* pcrel_offset */
128
129 HOWTO (R_BPF_DATA_16_PCREL,
130 0, /* rightshift */
131 1, /* size (0 = byte, 1 = short, 2 = long) */
132 16, /* bitsize */
133 TRUE, /* pc_relative */
134 0, /* bitpos */
135 complain_overflow_signed, /* complain_on_overflow */
136 bpf_elf_generic_reloc, /* special_function */
137 "R_BPF_16_PCREL", /* name */
138 FALSE, /* partial_inplace */
139 0xffff, /* src_mask */
140 0xffff, /* dst_mask */
141 TRUE), /* pcrel_offset */
142
143 HOWTO (R_BPF_DATA_32_PCREL,
144 0, /* rightshift */
145 2, /* size (0 = byte, 1 = short, 2 = long) */
146 32, /* bitsize */
147 TRUE, /* pc_relative */
148 0, /* bitpos */
149 complain_overflow_signed, /* complain_on_overflow */
150 bpf_elf_generic_reloc, /* special_function */
151 "R_BPF_32_PCREL", /* name */
152 FALSE, /* partial_inplace */
153 0xffffffff, /* src_mask */
154 0xffffffff, /* dst_mask */
155 TRUE), /* pcrel_offset */
156
157 HOWTO (R_BPF_DATA_8,
158 0, /* rightshift */
159 0, /* size (0 = byte, 1 = short, 2 = long) */
160 8, /* bitsize */
161 FALSE, /* pc_relative */
162 0, /* bitpos */
163 complain_overflow_unsigned, /* complain_on_overflow */
164 bpf_elf_generic_reloc, /* special_function */
165 "R_BPF_DATA_8", /* name */
166 TRUE, /* partial_inplace */
167 0xff, /* src_mask */
168 0xff, /* dst_mask */
169 FALSE), /* pcrel_offset */
170
171 HOWTO (R_BPF_DATA_16,
172 0, /* rightshift */
173 1, /* size (0 = byte, 1 = short, 2 = long) */
174 16, /* bitsize */
175 FALSE, /* pc_relative */
176 0, /* bitpos */
177 complain_overflow_unsigned, /* complain_on_overflow */
178 bpf_elf_generic_reloc, /* special_function */
179 "R_BPF_DATA_16", /* name */
180 FALSE, /* partial_inplace */
181 0xffff, /* src_mask */
182 0xffff, /* dst_mask */
183 FALSE), /* pcrel_offset */
184
185 /* 32-bit PC-relative address in call instructions. */
186 HOWTO (R_BPF_INSN_DISP32, /* type */
187 0, /* rightshift */
188 2, /* size (0 = byte, 1 = short, 2 = long) */
189 32, /* bitsize */
190 TRUE, /* pc_relative */
191 32, /* bitpos */
192 complain_overflow_signed, /* complain_on_overflow */
193 bpf_elf_generic_reloc, /* special_function */
194 "R_BPF_INSN_DISP32", /* name */
195 TRUE, /* partial_inplace */
196 0xffffffff, /* src_mask */
197 0xffffffff, /* dst_mask */
198 TRUE), /* pcrel_offset */
199
200 /* 32-bit data. */
201 HOWTO (R_BPF_DATA_32, /* type */
202 0, /* rightshift */
203 2, /* size (0 = byte, 1 = short, 2 = long) */
204 32, /* bitsize */
205 FALSE, /* pc_relative */
206 0, /* bitpos */
207 complain_overflow_bitfield, /* complain_on_overflow */
208 bpf_elf_generic_reloc, /* special_function */
209 "R_BPF_DATA_32", /* name */
210 FALSE, /* partial_inplace */
211 0xffffffff, /* src_mask */
212 0xffffffff, /* dst_mask */
213 TRUE), /* pcrel_offset */
214
215 /* 64-bit data. */
216 HOWTO (R_BPF_DATA_64, /* type */
217 0, /* rightshift */
218 4, /* size (0 = byte, 1 = short, 2 = long) */
219 64, /* bitsize */
220 FALSE, /* pc_relative */
221 0, /* bitpos */
222 complain_overflow_bitfield, /* complain_on_overflow */
223 bpf_elf_generic_reloc, /* special_function */
224 "R_BPF_DATA_64", /* name */
225 FALSE, /* partial_inplace */
226 0, /* src_mask */
227 MINUS_ONE, /* dst_mask */
228 TRUE), /* pcrel_offset */
229
230 HOWTO (R_BPF_DATA_64_PCREL,
231 0, /* rightshift */
232 4, /* size (0 = byte, 1 = short, 2 = long) */
233 64, /* bitsize */
234 TRUE, /* pc_relative */
235 0, /* bitpos */
236 complain_overflow_signed, /* complain_on_overflow */
237 bpf_elf_generic_reloc, /* special_function */
238 "R_BPF_64_PCREL", /* name */
239 FALSE, /* partial_inplace */
240 MINUS_ONE, /* src_mask */
241 MINUS_ONE, /* dst_mask */
242 TRUE), /* pcrel_offset */
243 };
244 #undef AHOW
245
246 /* Map BFD reloc types to bpf ELF reloc types. */
247
248 static reloc_howto_type *
249 bpf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
250 bfd_reloc_code_real_type code)
251 {
252 /* Note that the bpf_elf_howto_table is indexed by the R_ constants.
253 Thus, the order that the howto records appear in the table *must*
254 match the order of the relocation types defined in
255 include/elf/bpf.h. */
256
257 switch (code)
258 {
259 case BFD_RELOC_NONE:
260 return &bpf_elf_howto_table[ (int) R_BPF_NONE];
261
262 case BFD_RELOC_8_PCREL:
263 return &bpf_elf_howto_table[ (int) R_BPF_DATA_8_PCREL];
264 case BFD_RELOC_16_PCREL:
265 return &bpf_elf_howto_table[ (int) R_BPF_DATA_16_PCREL];
266 case BFD_RELOC_32_PCREL:
267 return &bpf_elf_howto_table[ (int) R_BPF_DATA_32_PCREL];
268 case BFD_RELOC_64_PCREL:
269 return &bpf_elf_howto_table[ (int) R_BPF_DATA_64_PCREL];
270
271 case BFD_RELOC_8:
272 return &bpf_elf_howto_table[ (int) R_BPF_DATA_8];
273 case BFD_RELOC_16:
274 return &bpf_elf_howto_table[ (int) R_BPF_DATA_16];
275 case BFD_RELOC_32:
276 return &bpf_elf_howto_table[ (int) R_BPF_DATA_32];
277 case BFD_RELOC_64:
278 return &bpf_elf_howto_table[ (int) R_BPF_DATA_64];
279
280 case BFD_RELOC_BPF_64:
281 return &bpf_elf_howto_table[ (int) R_BPF_INSN_64];
282 case BFD_RELOC_BPF_32:
283 return &bpf_elf_howto_table[ (int) R_BPF_INSN_32];
284 case BFD_RELOC_BPF_16:
285 return &bpf_elf_howto_table[ (int) R_BPF_INSN_16];
286 case BFD_RELOC_BPF_DISP16:
287 return &bpf_elf_howto_table[ (int) R_BPF_INSN_DISP16];
288 case BFD_RELOC_BPF_DISP32:
289 return &bpf_elf_howto_table[ (int) R_BPF_INSN_DISP32];
290
291 default:
292 /* Pacify gcc -Wall. */
293 return NULL;
294 }
295 return NULL;
296 }
297
298 /* Map BFD reloc names to bpf ELF reloc names. */
299
300 static reloc_howto_type *
301 bpf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
302 {
303 unsigned int i;
304
305 for (i = 0; i < ARRAY_SIZE (bpf_elf_howto_table); i++)
306 if (bpf_elf_howto_table[i].name != NULL
307 && strcasecmp (bpf_elf_howto_table[i].name, r_name) == 0)
308 return &bpf_elf_howto_table[i];
309
310 return NULL;
311 }
312
313 /* Set the howto pointer for a bpf reloc. */
314
315 static bfd_boolean
316 bpf_info_to_howto (bfd *abfd, arelent *bfd_reloc,
317 Elf_Internal_Rela *elf_reloc)
318 {
319 unsigned int r_type;
320
321 r_type = ELF64_R_TYPE (elf_reloc->r_info);
322 if (r_type >= (unsigned int) R_BPF_max)
323 {
324 /* xgettext:c-format */
325 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
326 abfd, r_type);
327 bfd_set_error (bfd_error_bad_value);
328 return FALSE;
329 }
330
331 bfd_reloc->howto = &bpf_elf_howto_table [r_type];
332 return TRUE;
333 }
334
335 /* Relocate an eBPF ELF section.
336
337 The RELOCATE_SECTION function is called by the new ELF backend linker
338 to handle the relocations for a section.
339
340 The relocs are always passed as Rela structures; if the section
341 actually uses Rel structures, the r_addend field will always be
342 zero.
343
344 This function is responsible for adjusting the section contents as
345 necessary, and (if using Rela relocs and generating a relocatable
346 output file) adjusting the reloc addend as necessary.
347
348 This function does not have to worry about setting the reloc
349 address or the reloc symbol index.
350
351 LOCAL_SYMS is a pointer to the swapped in local symbols.
352
353 LOCAL_SECTIONS is an array giving the section in the input file
354 corresponding to the st_shndx field of each local symbol.
355
356 The global hash table entry for the global symbols can be found
357 via elf_sym_hashes (input_bfd).
358
359 When generating relocatable output, this function must handle
360 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
361 going to be the section symbol corresponding to the output
362 section, which means that the addend must be adjusted
363 accordingly. */
364
365 #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
366
367 static bfd_boolean
368 bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
369 struct bfd_link_info *info,
370 bfd *input_bfd,
371 asection *input_section,
372 bfd_byte *contents,
373 Elf_Internal_Rela *relocs,
374 Elf_Internal_Sym *local_syms,
375 asection **local_sections)
376 {
377 Elf_Internal_Shdr *symtab_hdr;
378 struct elf_link_hash_entry **sym_hashes;
379 Elf_Internal_Rela *rel;
380 Elf_Internal_Rela *relend;
381
382 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
383 sym_hashes = elf_sym_hashes (input_bfd);
384 relend = relocs + input_section->reloc_count;
385
386 for (rel = relocs; rel < relend; rel ++)
387 {
388 reloc_howto_type * howto;
389 unsigned long r_symndx;
390 Elf_Internal_Sym * sym;
391 asection * sec;
392 struct elf_link_hash_entry * h;
393 bfd_vma relocation;
394 bfd_reloc_status_type r;
395 const char * name = NULL;
396 int r_type ATTRIBUTE_UNUSED;
397 bfd_signed_vma addend;
398 bfd_byte * where;
399
400 r_type = ELF64_R_TYPE (rel->r_info);
401 r_symndx = ELF64_R_SYM (rel->r_info);
402 howto = bpf_elf_howto_table + ELF64_R_TYPE (rel->r_info);
403 h = NULL;
404 sym = NULL;
405 sec = NULL;
406 where = contents + rel->r_offset;
407
408 if (r_symndx < symtab_hdr->sh_info)
409 {
410 sym = local_syms + r_symndx;
411 sec = local_sections [r_symndx];
412 relocation = BASEADDR (sec) + sym->st_value;
413
414 name = bfd_elf_string_from_elf_section
415 (input_bfd, symtab_hdr->sh_link, sym->st_name);
416 name = name == NULL ? bfd_section_name (sec) : name;
417 }
418 else
419 {
420 bfd_boolean warned ATTRIBUTE_UNUSED;
421 bfd_boolean unresolved_reloc ATTRIBUTE_UNUSED;
422 bfd_boolean ignored ATTRIBUTE_UNUSED;
423
424 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
425 r_symndx, symtab_hdr, sym_hashes,
426 h, sec, relocation,
427 unresolved_reloc, warned, ignored);
428
429 name = h->root.root.string;
430 }
431
432 if (sec != NULL && discarded_section (sec))
433 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
434 rel, 1, relend, howto, 0, contents);
435
436 if (bfd_link_relocatable (info))
437 continue;
438
439 switch (howto->type)
440 {
441 case R_BPF_INSN_DISP16:
442 case R_BPF_INSN_DISP32:
443 {
444 /* Make the relocation PC-relative, and change its unit to
445 64-bit words. Note we need *signed* arithmetic
446 here. */
447 relocation = ((bfd_signed_vma) relocation
448 - (sec_addr (input_section) + rel->r_offset));
449 relocation = (bfd_signed_vma) relocation / 8;
450
451 /* Get the addend from the instruction and apply it. */
452 addend = bfd_get (howto->bitsize, input_bfd,
453 contents + rel->r_offset
454 + (howto->bitsize == 16 ? 2 : 4));
455
456 if ((addend & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
457 addend -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
458 relocation += addend;
459
460 /* Write out the relocated value. */
461 bfd_put (howto->bitsize, input_bfd, relocation,
462 contents + rel->r_offset
463 + (howto->bitsize == 16 ? 2 : 4));
464
465 r = bfd_reloc_ok;
466 break;
467 }
468 case R_BPF_DATA_8:
469 case R_BPF_DATA_16:
470 case R_BPF_DATA_32:
471 case R_BPF_DATA_64:
472 {
473 addend = bfd_get (howto->bitsize, input_bfd, where);
474 relocation += addend;
475 bfd_put (howto->bitsize, input_bfd, relocation, where);
476
477 r = bfd_reloc_ok;
478 break;
479 }
480 case R_BPF_INSN_16:
481 {
482
483 addend = bfd_get_16 (input_bfd, where + 2);
484 relocation += addend;
485 bfd_put_16 (input_bfd, relocation, where + 2);
486
487 r = bfd_reloc_ok;
488 break;
489 }
490 case R_BPF_INSN_32:
491 {
492 /* Write relocated value */
493
494 addend = bfd_get_32 (input_bfd, where + 4);
495 relocation += addend;
496 bfd_put_32 (input_bfd, relocation, where + 4);
497
498 r = bfd_reloc_ok;
499 break;
500 }
501 case R_BPF_INSN_64:
502 {
503 /*
504 LDDW instructions are 128 bits long, with a 64-bit immediate.
505 The lower 32 bits of the immediate are in the same position
506 as the imm32 field of other instructions.
507 The upper 32 bits of the immediate are stored at the end of
508 the instruction.
509 */
510
511
512 /* Get the addend. The upper and lower 32 bits are split.
513 'where' is the beginning of the 16-byte instruction. */
514 addend = bfd_get_32 (input_bfd, where + 4);
515 addend |= (bfd_get_32 (input_bfd, where + 12) << 32);
516
517 relocation += addend;
518
519 bfd_put_32 (input_bfd, (relocation & 0xFFFFFFFF), where + 4);
520 bfd_put_32 (input_bfd, (relocation >> 32), where + 12);
521 r = bfd_reloc_ok;
522 break;
523 }
524 default:
525 r = bfd_reloc_notsupported;
526 }
527
528 if (r == bfd_reloc_ok)
529 r = bfd_check_overflow (howto->complain_on_overflow,
530 howto->bitsize,
531 howto->rightshift,
532 64, relocation);
533
534 if (r != bfd_reloc_ok)
535 {
536 const char * msg = NULL;
537
538 switch (r)
539 {
540 case bfd_reloc_overflow:
541 (*info->callbacks->reloc_overflow)
542 (info, (h ? &h->root : NULL), name, howto->name,
543 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
544 break;
545
546 case bfd_reloc_undefined:
547 (*info->callbacks->undefined_symbol)
548 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
549 break;
550
551 case bfd_reloc_outofrange:
552 msg = _("internal error: out of range error");
553 break;
554
555 case bfd_reloc_notsupported:
556 if (sym != NULL) /* Only if it's not an unresolved symbol. */
557 msg = _("internal error: relocation not supported");
558 break;
559
560 case bfd_reloc_dangerous:
561 msg = _("internal error: dangerous relocation");
562 break;
563
564 default:
565 msg = _("internal error: unknown error");
566 break;
567 }
568
569 if (msg)
570 (*info->callbacks->warning) (info, msg, name, input_bfd,
571 input_section, rel->r_offset);
572 }
573 }
574
575 return TRUE;
576 }
577
578 /* Merge backend specific data from an object file to the output
579 object file when linking. */
580
581 static bfd_boolean
582 elf64_bpf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
583 {
584 /* Check if we have the same endianness. */
585 if (! _bfd_generic_verify_endian_match (ibfd, info))
586 return FALSE;
587
588 return TRUE;
589 }
590
591 /* A generic howto special function for installing BPF relocations.
592 This function will be called by the assembler (via bfd_install_relocation).
593 At link time, bpf_elf_relocate_section will resolve the final relocations.
594
595 BPF instructions are always big endian, and this approach avoids problems in
596 bfd_install_relocation. */
597
598 static bfd_reloc_status_type
599 bpf_elf_generic_reloc (bfd * abfd, arelent *reloc_entry, asymbol *symbol,
600 void *data, asection *input_section,
601 bfd *output_bfd,
602 char **error_message ATTRIBUTE_UNUSED)
603 {
604
605 bfd_signed_vma relocation;
606 bfd_reloc_status_type status;
607 bfd_byte *where;
608
609 /* Sanity check that the address is in range. */
610 if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
611 return bfd_reloc_outofrange;
612
613 /* Get the symbol value. */
614 if (bfd_is_com_section (symbol->section))
615 relocation = 0;
616 else
617 relocation = symbol->value;
618
619 if (symbol->flags & BSF_SECTION_SYM)
620 /* Relocation against a section symbol: add in the section base address. */
621 relocation += BASEADDR (symbol->section);
622
623 relocation += reloc_entry->addend;
624
625 where = (bfd_byte *) data + reloc_entry->address;
626
627 status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow,
628 reloc_entry->howto->bitsize,
629 reloc_entry->howto->rightshift, 64, relocation);
630
631 if (status != bfd_reloc_ok)
632 return status;
633
634 /* Now finally install the relocation. */
635 if (reloc_entry->howto->type == R_BPF_INSN_64)
636 {
637 /* lddw is a 128-bit (!) instruction that allows loading a 64-bit
638 immediate into a register. the immediate is split in half, with the
639 lower 32 bits in the same position as the imm32 field of other
640 instructions, and the upper 32 bits placed at the very end of the
641 instruction. that is, there are 32 unused bits between them. */
642
643 bfd_put_32 (output_bfd, (relocation & 0xFFFFFFFF), where + 4);
644 bfd_put_32 (output_bfd, (relocation >> 32), where + 12);
645 }
646 else
647 {
648 /* For other kinds of relocations, the relocated value simply goes
649 BITPOS bits from the start of the entry. This is always a multiple
650 of 8, i.e. whole bytes. */
651 bfd_put (reloc_entry->howto->bitsize, output_bfd, relocation,
652 where + reloc_entry->howto->bitpos / 8);
653 }
654
655 reloc_entry->addend = relocation;
656 reloc_entry->address += input_section->output_offset;
657
658 return bfd_reloc_ok;
659 }
660
661
662 /* The macros below configure the architecture. */
663
664 #define TARGET_LITTLE_SYM bpf_elf64_le_vec
665 #define TARGET_LITTLE_NAME "elf64-bpfle"
666
667 #define TARGET_BIG_SYM bpf_elf64_be_vec
668 #define TARGET_BIG_NAME "elf64-bpfbe"
669
670 #define ELF_ARCH bfd_arch_bpf
671 #define ELF_MACHINE_CODE EM_BPF
672
673 #define ELF_MAXPAGESIZE 0x100000
674
675 #define elf_info_to_howto_rel bpf_info_to_howto
676 #define elf_info_to_howto bpf_info_to_howto
677
678 #define elf_backend_may_use_rel_p 1
679 #define elf_backend_may_use_rela_p 0
680 #define elf_backend_default_use_rela_p 0
681 #define elf_backend_relocate_section bpf_elf_relocate_section
682
683 #define elf_backend_can_gc_sections 0
684
685 #define elf_symbol_leading_char '_'
686 #define bfd_elf64_bfd_reloc_type_lookup bpf_reloc_type_lookup
687 #define bfd_elf64_bfd_reloc_name_lookup bpf_reloc_name_lookup
688
689 #define bfd_elf64_bfd_merge_private_bfd_data elf64_bpf_merge_private_bfd_data
690
691 #include "elf64-target.h"
This page took 0.057552 seconds and 4 git commands to generate.