]> Git Repo - binutils.git/blob - bfd/elf64-bpf.c
Automatic date update in version.in
[binutils.git] / bfd / elf64-bpf.c
1 /* Linux bpf specific support for 64-bit ELF
2    Copyright (C) 2019-2022 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          0,                     /* size */
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          8,                     /* size */
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          4,                     /* size */
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          2,                     /* size */
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          2,                     /* size */
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          1,                     /* size */
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          2,                     /* size */
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          4,                     /* size */
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          1,                     /* size */
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          2,                     /* size */
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          4,                     /* size */
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          4,                     /* size */
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          8,                     /* size */
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          8,                     /* size */
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 bool
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 int
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           bool warned ATTRIBUTE_UNUSED;
421           bool unresolved_reloc ATTRIBUTE_UNUSED;
422           bool 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 bool
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    and by various get_relocated_section_contents functions.
594    At link time, bpf_elf_relocate_section will resolve the final relocations.
595
596    BPF instructions are always big endian, and this approach avoids problems in
597    bfd_install_relocation.  */
598
599 static bfd_reloc_status_type
600 bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
601                        void *data, asection *input_section,
602                        bfd *output_bfd ATTRIBUTE_UNUSED,
603                        char **error_message ATTRIBUTE_UNUSED)
604 {
605
606   bfd_signed_vma relocation;
607   bfd_reloc_status_type status;
608   bfd_byte *where;
609
610   /* Sanity check that the address is in range.  */
611   bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section);
612   bfd_size_type reloc_size;
613   if (reloc_entry->howto->type == R_BPF_INSN_64)
614     reloc_size = 16;
615   else
616     reloc_size = (reloc_entry->howto->bitsize
617                   + reloc_entry->howto->bitpos) / 8;
618
619   if (reloc_entry->address > end
620       || end - reloc_entry->address < reloc_size)
621     return bfd_reloc_outofrange;
622
623   /*  Get the symbol value.  */
624   if (bfd_is_com_section (symbol->section))
625     relocation = 0;
626   else
627     relocation = symbol->value;
628
629   if (symbol->flags & BSF_SECTION_SYM)
630     /* Relocation against a section symbol: add in the section base address.  */
631     relocation += BASEADDR (symbol->section);
632
633   relocation += reloc_entry->addend;
634
635   where = (bfd_byte *) data + reloc_entry->address;
636
637   status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow,
638                                reloc_entry->howto->bitsize,
639                                reloc_entry->howto->rightshift, 64, relocation);
640
641   if (status != bfd_reloc_ok)
642     return status;
643
644   /* Now finally install the relocation.  */
645   if (reloc_entry->howto->type == R_BPF_INSN_64)
646     {
647       /* lddw is a 128-bit (!) instruction that allows loading a 64-bit
648          immediate into a register. the immediate is split in half, with the
649          lower 32 bits in the same position as the imm32 field of other
650          instructions, and the upper 32 bits placed at the very end of the
651          instruction. that is, there are 32 unused bits between them. */
652
653       bfd_put_32 (abfd, (relocation & 0xFFFFFFFF), where + 4);
654       bfd_put_32 (abfd, (relocation >> 32), where + 12);
655     }
656   else
657     {
658       /* For other kinds of relocations, the relocated value simply goes
659          BITPOS bits from the start of the entry. This is always a multiple
660          of 8, i.e. whole bytes.  */
661       bfd_put (reloc_entry->howto->bitsize, abfd, relocation,
662                where + reloc_entry->howto->bitpos / 8);
663     }
664
665   reloc_entry->addend = relocation;
666   reloc_entry->address += input_section->output_offset;
667
668   return bfd_reloc_ok;
669 }
670
671
672 /* The macros below configure the architecture.  */
673
674 #define TARGET_LITTLE_SYM bpf_elf64_le_vec
675 #define TARGET_LITTLE_NAME "elf64-bpfle"
676
677 #define TARGET_BIG_SYM bpf_elf64_be_vec
678 #define TARGET_BIG_NAME "elf64-bpfbe"
679
680 #define ELF_ARCH bfd_arch_bpf
681 #define ELF_MACHINE_CODE EM_BPF
682
683 #define ELF_MAXPAGESIZE 0x100000
684
685 #define elf_info_to_howto_rel bpf_info_to_howto
686 #define elf_info_to_howto bpf_info_to_howto
687
688 #define elf_backend_may_use_rel_p               1
689 #define elf_backend_may_use_rela_p              0
690 #define elf_backend_default_use_rela_p          0
691 #define elf_backend_relocate_section            bpf_elf_relocate_section
692
693 #define elf_backend_can_gc_sections             0
694
695 #define elf_symbol_leading_char                 '_'
696 #define bfd_elf64_bfd_reloc_type_lookup         bpf_reloc_type_lookup
697 #define bfd_elf64_bfd_reloc_name_lookup         bpf_reloc_name_lookup
698
699 #define bfd_elf64_bfd_merge_private_bfd_data elf64_bpf_merge_private_bfd_data
700
701 #include "elf64-target.h"
This page took 0.063499 seconds and 4 git commands to generate.