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