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
34static bfd_reloc_status_type bpf_elf_generic_reloc
35  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
36
37/* Relocation tables.  */
38static 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
248static reloc_howto_type *
249bpf_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
300static reloc_howto_type *
301bpf_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
315static bool
316bpf_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
367static int
368bpf_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
581static bool
582elf64_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
599static bfd_reloc_status_type
600bpf_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"
702