1 1.1 christos /* Linux bpf specific support for 64-bit ELF 2 1.1.1.5 christos Copyright (C) 2019-2026 Free Software Foundation, Inc. 3 1.1 christos Contributed by Oracle Inc. 4 1.1 christos 5 1.1 christos This file is part of BFD, the Binary File Descriptor library. 6 1.1 christos 7 1.1 christos This program is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3 of the License, or 10 1.1 christos (at your option) any later version. 11 1.1 christos 12 1.1 christos This program is distributed in the hope that it will be useful, 13 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 14 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 1.1 christos GNU General Public License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this program; if not, write to the Free Software 19 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1 christos #include "sysdep.h" 23 1.1 christos #include "bfd.h" 24 1.1 christos #include "libbfd.h" 25 1.1 christos #include "elf-bfd.h" 26 1.1 christos #include "elf/bpf.h" 27 1.1 christos #include "libiberty.h" 28 1.1 christos 29 1.1 christos /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */ 30 1.1 christos #define MINUS_ONE (~ (bfd_vma) 0) 31 1.1 christos 32 1.1 christos #define BASEADDR(SEC) ((SEC)->output_section->vma + (SEC)->output_offset) 33 1.1 christos 34 1.1.1.2 christos static bfd_reloc_status_type bpf_elf_generic_reloc 35 1.1.1.2 christos (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); 36 1.1.1.2 christos 37 1.1.1.3 christos #undef BPF_HOWTO 38 1.1.1.3 christos #define BPF_HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \ 39 1.1.1.3 christos inplace, src_mask, dst_mask, pcrel_off) \ 40 1.1.1.3 christos type##_IDX, 41 1.1.1.3 christos enum bpf_reloc_index { 42 1.1.1.3 christos R_BPF_INVALID_IDX = -1, 43 1.1.1.3 christos #include "bpf-reloc.def" 44 1.1.1.3 christos R_BPF_SIZE 45 1.1.1.3 christos }; 46 1.1.1.3 christos #undef BPF_HOWTO 47 1.1.1.3 christos 48 1.1 christos /* Relocation tables. */ 49 1.1.1.3 christos #define BPF_HOWTO(...) HOWTO(__VA_ARGS__), 50 1.1 christos static reloc_howto_type bpf_elf_howto_table [] = 51 1.1 christos { 52 1.1.1.3 christos #include "bpf-reloc.def" 53 1.1 christos }; 54 1.1 christos #undef AHOW 55 1.1.1.3 christos #undef BPF_HOWTO 56 1.1.1.3 christos 57 1.1.1.3 christos #define BPF_HOWTO(type, right, size, bits, pcrel, left, ovf, func, name, \ 58 1.1.1.3 christos inplace, src_mask, dst_mask, pcrel_off) \ 59 1.1.1.3 christos case type: { return type##_IDX; } 60 1.1.1.3 christos static enum bpf_reloc_index 61 1.1.1.3 christos bpf_index_for_rtype(unsigned int r_type) 62 1.1.1.3 christos { 63 1.1.1.3 christos switch(r_type) { 64 1.1.1.3 christos #include "bpf-reloc.def" 65 1.1.1.3 christos default: 66 1.1.1.3 christos /* Unreachable code. */ 67 1.1.1.3 christos BFD_ASSERT(0); 68 1.1.1.3 christos return -1; 69 1.1.1.3 christos }; 70 1.1.1.3 christos } 71 1.1 christos 72 1.1 christos /* Map BFD reloc types to bpf ELF reloc types. */ 73 1.1 christos 74 1.1 christos static reloc_howto_type * 75 1.1 christos bpf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED, 76 1.1 christos bfd_reloc_code_real_type code) 77 1.1 christos { 78 1.1 christos switch (code) 79 1.1 christos { 80 1.1 christos case BFD_RELOC_NONE: 81 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_NONE_IDX]; 82 1.1 christos 83 1.1 christos case BFD_RELOC_32: 84 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_64_ABS32_IDX]; 85 1.1 christos case BFD_RELOC_64: 86 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_64_ABS64_IDX]; 87 1.1 christos 88 1.1 christos case BFD_RELOC_BPF_64: 89 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_64_64_IDX]; 90 1.1 christos case BFD_RELOC_BPF_DISP32: 91 1.1.1.3 christos case BFD_RELOC_BPF_DISPCALL32: 92 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_64_32_IDX]; 93 1.1.1.3 christos case BFD_RELOC_BPF_DISP16: 94 1.1.1.3 christos return &bpf_elf_howto_table[ (int) R_BPF_GNU_64_16_IDX]; 95 1.1 christos 96 1.1 christos default: 97 1.1 christos /* Pacify gcc -Wall. */ 98 1.1 christos return NULL; 99 1.1 christos } 100 1.1 christos return NULL; 101 1.1 christos } 102 1.1 christos 103 1.1 christos /* Map BFD reloc names to bpf ELF reloc names. */ 104 1.1 christos 105 1.1 christos static reloc_howto_type * 106 1.1 christos bpf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) 107 1.1 christos { 108 1.1 christos unsigned int i; 109 1.1 christos 110 1.1.1.3 christos for (i = 0; i < R_BPF_SIZE; i++) 111 1.1 christos if (bpf_elf_howto_table[i].name != NULL 112 1.1 christos && strcasecmp (bpf_elf_howto_table[i].name, r_name) == 0) 113 1.1 christos return &bpf_elf_howto_table[i]; 114 1.1 christos 115 1.1 christos return NULL; 116 1.1 christos } 117 1.1 christos 118 1.1 christos /* Set the howto pointer for a bpf reloc. */ 119 1.1 christos 120 1.1.1.2 christos static bool 121 1.1 christos bpf_info_to_howto (bfd *abfd, arelent *bfd_reloc, 122 1.1 christos Elf_Internal_Rela *elf_reloc) 123 1.1 christos { 124 1.1 christos unsigned int r_type; 125 1.1.1.3 christos unsigned int i; 126 1.1 christos r_type = ELF64_R_TYPE (elf_reloc->r_info); 127 1.1.1.3 christos 128 1.1.1.3 christos i = bpf_index_for_rtype(r_type); 129 1.1.1.3 christos if (i == (unsigned int) -1) 130 1.1 christos { 131 1.1 christos /* xgettext:c-format */ 132 1.1 christos _bfd_error_handler (_("%pB: unsupported relocation type %#x"), 133 1.1 christos abfd, r_type); 134 1.1 christos bfd_set_error (bfd_error_bad_value); 135 1.1.1.2 christos return false; 136 1.1 christos } 137 1.1 christos 138 1.1.1.3 christos bfd_reloc->howto = &bpf_elf_howto_table [i]; 139 1.1.1.2 christos return true; 140 1.1 christos } 141 1.1 christos 142 1.1 christos /* Relocate an eBPF ELF section. 143 1.1 christos 144 1.1 christos The RELOCATE_SECTION function is called by the new ELF backend linker 145 1.1 christos to handle the relocations for a section. 146 1.1 christos 147 1.1 christos The relocs are always passed as Rela structures; if the section 148 1.1 christos actually uses Rel structures, the r_addend field will always be 149 1.1 christos zero. 150 1.1 christos 151 1.1 christos This function is responsible for adjusting the section contents as 152 1.1 christos necessary, and (if using Rela relocs and generating a relocatable 153 1.1 christos output file) adjusting the reloc addend as necessary. 154 1.1 christos 155 1.1 christos This function does not have to worry about setting the reloc 156 1.1 christos address or the reloc symbol index. 157 1.1 christos 158 1.1 christos LOCAL_SYMS is a pointer to the swapped in local symbols. 159 1.1 christos 160 1.1 christos LOCAL_SECTIONS is an array giving the section in the input file 161 1.1 christos corresponding to the st_shndx field of each local symbol. 162 1.1 christos 163 1.1 christos The global hash table entry for the global symbols can be found 164 1.1 christos via elf_sym_hashes (input_bfd). 165 1.1 christos 166 1.1 christos When generating relocatable output, this function must handle 167 1.1 christos STB_LOCAL/STT_SECTION symbols specially. The output symbol is 168 1.1 christos going to be the section symbol corresponding to the output 169 1.1 christos section, which means that the addend must be adjusted 170 1.1 christos accordingly. */ 171 1.1 christos 172 1.1 christos #define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset) 173 1.1 christos 174 1.1.1.2 christos static int 175 1.1 christos bpf_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED, 176 1.1 christos struct bfd_link_info *info, 177 1.1 christos bfd *input_bfd, 178 1.1 christos asection *input_section, 179 1.1 christos bfd_byte *contents, 180 1.1 christos Elf_Internal_Rela *relocs, 181 1.1 christos Elf_Internal_Sym *local_syms, 182 1.1 christos asection **local_sections) 183 1.1 christos { 184 1.1 christos Elf_Internal_Shdr *symtab_hdr; 185 1.1 christos struct elf_link_hash_entry **sym_hashes; 186 1.1 christos Elf_Internal_Rela *rel; 187 1.1 christos Elf_Internal_Rela *relend; 188 1.1 christos 189 1.1 christos symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr; 190 1.1 christos sym_hashes = elf_sym_hashes (input_bfd); 191 1.1 christos relend = relocs + input_section->reloc_count; 192 1.1 christos 193 1.1 christos for (rel = relocs; rel < relend; rel ++) 194 1.1 christos { 195 1.1 christos reloc_howto_type * howto; 196 1.1.1.3 christos unsigned int howto_index; 197 1.1 christos unsigned long r_symndx; 198 1.1 christos Elf_Internal_Sym * sym; 199 1.1 christos asection * sec; 200 1.1 christos struct elf_link_hash_entry * h; 201 1.1 christos bfd_vma relocation; 202 1.1 christos bfd_reloc_status_type r; 203 1.1 christos const char * name = NULL; 204 1.1 christos int r_type ATTRIBUTE_UNUSED; 205 1.1.1.2 christos bfd_signed_vma addend; 206 1.1.1.2 christos bfd_byte * where; 207 1.1 christos 208 1.1 christos r_type = ELF64_R_TYPE (rel->r_info); 209 1.1 christos r_symndx = ELF64_R_SYM (rel->r_info); 210 1.1.1.3 christos 211 1.1.1.3 christos howto_index = bpf_index_for_rtype (ELF64_R_TYPE (rel->r_info)); 212 1.1.1.3 christos howto = &bpf_elf_howto_table[howto_index]; 213 1.1 christos h = NULL; 214 1.1 christos sym = NULL; 215 1.1 christos sec = NULL; 216 1.1.1.2 christos where = contents + rel->r_offset; 217 1.1 christos 218 1.1 christos if (r_symndx < symtab_hdr->sh_info) 219 1.1 christos { 220 1.1 christos sym = local_syms + r_symndx; 221 1.1 christos sec = local_sections [r_symndx]; 222 1.1 christos relocation = BASEADDR (sec) + sym->st_value; 223 1.1 christos 224 1.1 christos name = bfd_elf_string_from_elf_section 225 1.1 christos (input_bfd, symtab_hdr->sh_link, sym->st_name); 226 1.1 christos name = name == NULL ? bfd_section_name (sec) : name; 227 1.1 christos } 228 1.1 christos else 229 1.1 christos { 230 1.1.1.2 christos bool warned ATTRIBUTE_UNUSED; 231 1.1.1.2 christos bool unresolved_reloc ATTRIBUTE_UNUSED; 232 1.1.1.2 christos bool ignored ATTRIBUTE_UNUSED; 233 1.1 christos 234 1.1 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel, 235 1.1 christos r_symndx, symtab_hdr, sym_hashes, 236 1.1 christos h, sec, relocation, 237 1.1 christos unresolved_reloc, warned, ignored); 238 1.1 christos 239 1.1 christos name = h->root.root.string; 240 1.1 christos } 241 1.1 christos 242 1.1 christos if (sec != NULL && discarded_section (sec)) 243 1.1 christos RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section, 244 1.1.1.5 christos rel, 1, relend, R_BPF_NONE, 245 1.1.1.5 christos howto, 0, contents); 246 1.1 christos 247 1.1 christos if (bfd_link_relocatable (info)) 248 1.1 christos continue; 249 1.1 christos 250 1.1 christos switch (howto->type) 251 1.1 christos { 252 1.1.1.3 christos case R_BPF_64_32: 253 1.1 christos { 254 1.1 christos /* Make the relocation PC-relative, and change its unit to 255 1.1.1.2 christos 64-bit words. Note we need *signed* arithmetic 256 1.1.1.2 christos here. */ 257 1.1.1.2 christos relocation = ((bfd_signed_vma) relocation 258 1.1.1.2 christos - (sec_addr (input_section) + rel->r_offset)); 259 1.1.1.2 christos relocation = (bfd_signed_vma) relocation / 8; 260 1.1 christos 261 1.1 christos /* Get the addend from the instruction and apply it. */ 262 1.1 christos addend = bfd_get (howto->bitsize, input_bfd, 263 1.1 christos contents + rel->r_offset 264 1.1 christos + (howto->bitsize == 16 ? 2 : 4)); 265 1.1 christos 266 1.1 christos if ((addend & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0) 267 1.1 christos addend -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1; 268 1.1 christos relocation += addend; 269 1.1 christos 270 1.1 christos /* Write out the relocated value. */ 271 1.1 christos bfd_put (howto->bitsize, input_bfd, relocation, 272 1.1 christos contents + rel->r_offset 273 1.1 christos + (howto->bitsize == 16 ? 2 : 4)); 274 1.1 christos 275 1.1 christos r = bfd_reloc_ok; 276 1.1 christos break; 277 1.1 christos } 278 1.1.1.3 christos case R_BPF_64_ABS64: 279 1.1.1.3 christos case R_BPF_64_ABS32: 280 1.1.1.3 christos case R_BPF_64_NODYLD32: 281 1.1.1.2 christos { 282 1.1.1.2 christos addend = bfd_get (howto->bitsize, input_bfd, where); 283 1.1.1.2 christos relocation += addend; 284 1.1.1.2 christos bfd_put (howto->bitsize, input_bfd, relocation, where); 285 1.1.1.2 christos 286 1.1.1.2 christos r = bfd_reloc_ok; 287 1.1.1.2 christos break; 288 1.1.1.2 christos } 289 1.1.1.3 christos case R_BPF_64_64: 290 1.1.1.2 christos { 291 1.1.1.2 christos /* 292 1.1.1.2 christos LDDW instructions are 128 bits long, with a 64-bit immediate. 293 1.1.1.2 christos The lower 32 bits of the immediate are in the same position 294 1.1.1.2 christos as the imm32 field of other instructions. 295 1.1.1.2 christos The upper 32 bits of the immediate are stored at the end of 296 1.1.1.2 christos the instruction. 297 1.1.1.2 christos */ 298 1.1.1.2 christos 299 1.1.1.2 christos 300 1.1.1.2 christos /* Get the addend. The upper and lower 32 bits are split. 301 1.1.1.2 christos 'where' is the beginning of the 16-byte instruction. */ 302 1.1.1.2 christos addend = bfd_get_32 (input_bfd, where + 4); 303 1.1.1.2 christos addend |= (bfd_get_32 (input_bfd, where + 12) << 32); 304 1.1.1.2 christos 305 1.1.1.2 christos relocation += addend; 306 1.1.1.2 christos 307 1.1.1.2 christos bfd_put_32 (input_bfd, (relocation & 0xFFFFFFFF), where + 4); 308 1.1.1.2 christos bfd_put_32 (input_bfd, (relocation >> 32), where + 12); 309 1.1.1.2 christos r = bfd_reloc_ok; 310 1.1.1.2 christos break; 311 1.1.1.2 christos } 312 1.1 christos default: 313 1.1.1.2 christos r = bfd_reloc_notsupported; 314 1.1 christos } 315 1.1 christos 316 1.1.1.2 christos if (r == bfd_reloc_ok) 317 1.1.1.2 christos r = bfd_check_overflow (howto->complain_on_overflow, 318 1.1.1.2 christos howto->bitsize, 319 1.1.1.2 christos howto->rightshift, 320 1.1.1.2 christos 64, relocation); 321 1.1.1.2 christos 322 1.1 christos if (r != bfd_reloc_ok) 323 1.1 christos { 324 1.1 christos const char * msg = NULL; 325 1.1 christos 326 1.1 christos switch (r) 327 1.1 christos { 328 1.1 christos case bfd_reloc_overflow: 329 1.1 christos (*info->callbacks->reloc_overflow) 330 1.1 christos (info, (h ? &h->root : NULL), name, howto->name, 331 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset); 332 1.1 christos break; 333 1.1 christos 334 1.1 christos case bfd_reloc_undefined: 335 1.1 christos (*info->callbacks->undefined_symbol) 336 1.1.1.2 christos (info, name, input_bfd, input_section, rel->r_offset, true); 337 1.1 christos break; 338 1.1 christos 339 1.1 christos case bfd_reloc_outofrange: 340 1.1 christos msg = _("internal error: out of range error"); 341 1.1 christos break; 342 1.1 christos 343 1.1 christos case bfd_reloc_notsupported: 344 1.1 christos if (sym != NULL) /* Only if it's not an unresolved symbol. */ 345 1.1 christos msg = _("internal error: relocation not supported"); 346 1.1 christos break; 347 1.1 christos 348 1.1 christos case bfd_reloc_dangerous: 349 1.1 christos msg = _("internal error: dangerous relocation"); 350 1.1 christos break; 351 1.1 christos 352 1.1 christos default: 353 1.1 christos msg = _("internal error: unknown error"); 354 1.1 christos break; 355 1.1 christos } 356 1.1 christos 357 1.1 christos if (msg) 358 1.1 christos (*info->callbacks->warning) (info, msg, name, input_bfd, 359 1.1 christos input_section, rel->r_offset); 360 1.1 christos } 361 1.1 christos } 362 1.1 christos 363 1.1.1.2 christos return true; 364 1.1 christos } 365 1.1 christos 366 1.1 christos /* Merge backend specific data from an object file to the output 367 1.1 christos object file when linking. */ 368 1.1 christos 369 1.1.1.2 christos static bool 370 1.1 christos elf64_bpf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info) 371 1.1 christos { 372 1.1 christos /* Check if we have the same endianness. */ 373 1.1 christos if (! _bfd_generic_verify_endian_match (ibfd, info)) 374 1.1.1.2 christos return false; 375 1.1 christos 376 1.1.1.2 christos return true; 377 1.1 christos } 378 1.1 christos 379 1.1.1.2 christos /* A generic howto special function for installing BPF relocations. 380 1.1.1.2 christos This function will be called by the assembler (via bfd_install_relocation), 381 1.1.1.2 christos and by various get_relocated_section_contents functions. 382 1.1.1.2 christos At link time, bpf_elf_relocate_section will resolve the final relocations. 383 1.1.1.2 christos 384 1.1.1.2 christos BPF instructions are always big endian, and this approach avoids problems in 385 1.1.1.2 christos bfd_install_relocation. */ 386 1.1.1.2 christos 387 1.1.1.2 christos static bfd_reloc_status_type 388 1.1.1.2 christos bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, 389 1.1.1.3 christos void *data, asection *input_section, bfd *output_bfd, 390 1.1.1.2 christos char **error_message ATTRIBUTE_UNUSED) 391 1.1.1.2 christos { 392 1.1.1.2 christos 393 1.1.1.2 christos bfd_signed_vma relocation; 394 1.1.1.2 christos bfd_reloc_status_type status; 395 1.1.1.2 christos bfd_byte *where; 396 1.1.1.2 christos 397 1.1.1.3 christos /* From bfd_elf_generic_reloc. */ 398 1.1.1.3 christos if (output_bfd != NULL 399 1.1.1.3 christos && (symbol->flags & BSF_SECTION_SYM) == 0 400 1.1.1.3 christos && (! reloc_entry->howto->partial_inplace 401 1.1.1.3 christos || reloc_entry->addend == 0)) 402 1.1.1.3 christos { 403 1.1.1.3 christos reloc_entry->address += input_section->output_offset; 404 1.1.1.3 christos return bfd_reloc_ok; 405 1.1.1.3 christos } 406 1.1.1.3 christos 407 1.1.1.3 christos if (output_bfd == NULL 408 1.1.1.3 christos && !reloc_entry->howto->pc_relative 409 1.1.1.3 christos && (symbol->section->flags & SEC_DEBUGGING) != 0 410 1.1.1.3 christos && (input_section->flags & SEC_DEBUGGING) != 0) 411 1.1.1.3 christos reloc_entry->addend -= symbol->section->output_section->vma; 412 1.1.1.3 christos 413 1.1.1.2 christos /* Sanity check that the address is in range. */ 414 1.1.1.2 christos bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section); 415 1.1.1.2 christos bfd_size_type reloc_size; 416 1.1.1.3 christos if (reloc_entry->howto->type == R_BPF_64_64) 417 1.1.1.2 christos reloc_size = 16; 418 1.1.1.2 christos else 419 1.1.1.2 christos reloc_size = (reloc_entry->howto->bitsize 420 1.1.1.2 christos + reloc_entry->howto->bitpos) / 8; 421 1.1.1.2 christos 422 1.1.1.2 christos if (reloc_entry->address > end 423 1.1.1.2 christos || end - reloc_entry->address < reloc_size) 424 1.1.1.2 christos return bfd_reloc_outofrange; 425 1.1.1.2 christos 426 1.1.1.3 christos /* Behave similarly to bfd_install_relocation with install_addend set. 427 1.1.1.3 christos That is, just install the addend and do not include the value of 428 1.1.1.3 christos the symbol. */ 429 1.1.1.3 christos relocation = reloc_entry->addend; 430 1.1.1.2 christos 431 1.1.1.2 christos if (symbol->flags & BSF_SECTION_SYM) 432 1.1.1.2 christos /* Relocation against a section symbol: add in the section base address. */ 433 1.1.1.2 christos relocation += BASEADDR (symbol->section); 434 1.1.1.2 christos 435 1.1.1.2 christos where = (bfd_byte *) data + reloc_entry->address; 436 1.1.1.2 christos 437 1.1.1.2 christos status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow, 438 1.1.1.2 christos reloc_entry->howto->bitsize, 439 1.1.1.2 christos reloc_entry->howto->rightshift, 64, relocation); 440 1.1.1.2 christos 441 1.1.1.2 christos if (status != bfd_reloc_ok) 442 1.1.1.2 christos return status; 443 1.1.1.2 christos 444 1.1.1.2 christos /* Now finally install the relocation. */ 445 1.1.1.3 christos if (reloc_entry->howto->type == R_BPF_64_64) 446 1.1.1.2 christos { 447 1.1.1.2 christos /* lddw is a 128-bit (!) instruction that allows loading a 64-bit 448 1.1.1.2 christos immediate into a register. the immediate is split in half, with the 449 1.1.1.2 christos lower 32 bits in the same position as the imm32 field of other 450 1.1.1.2 christos instructions, and the upper 32 bits placed at the very end of the 451 1.1.1.2 christos instruction. that is, there are 32 unused bits between them. */ 452 1.1.1.2 christos 453 1.1.1.2 christos bfd_put_32 (abfd, (relocation & 0xFFFFFFFF), where + 4); 454 1.1.1.2 christos bfd_put_32 (abfd, (relocation >> 32), where + 12); 455 1.1.1.2 christos } 456 1.1.1.2 christos else 457 1.1.1.2 christos { 458 1.1.1.2 christos /* For other kinds of relocations, the relocated value simply goes 459 1.1.1.2 christos BITPOS bits from the start of the entry. This is always a multiple 460 1.1.1.2 christos of 8, i.e. whole bytes. */ 461 1.1.1.2 christos bfd_put (reloc_entry->howto->bitsize, abfd, relocation, 462 1.1.1.2 christos where + reloc_entry->howto->bitpos / 8); 463 1.1.1.2 christos } 464 1.1.1.2 christos 465 1.1.1.3 christos if (output_bfd != NULL) 466 1.1.1.3 christos reloc_entry->address += input_section->output_offset; 467 1.1.1.2 christos 468 1.1.1.2 christos return bfd_reloc_ok; 469 1.1.1.2 christos } 470 1.1.1.2 christos 471 1.1.1.2 christos 472 1.1 christos /* The macros below configure the architecture. */ 473 1.1 christos 474 1.1 christos #define TARGET_LITTLE_SYM bpf_elf64_le_vec 475 1.1 christos #define TARGET_LITTLE_NAME "elf64-bpfle" 476 1.1 christos 477 1.1 christos #define TARGET_BIG_SYM bpf_elf64_be_vec 478 1.1 christos #define TARGET_BIG_NAME "elf64-bpfbe" 479 1.1 christos 480 1.1 christos #define ELF_ARCH bfd_arch_bpf 481 1.1 christos #define ELF_MACHINE_CODE EM_BPF 482 1.1 christos 483 1.1 christos #define ELF_MAXPAGESIZE 0x100000 484 1.1 christos 485 1.1 christos #define elf_info_to_howto_rel bpf_info_to_howto 486 1.1 christos #define elf_info_to_howto bpf_info_to_howto 487 1.1 christos 488 1.1 christos #define elf_backend_may_use_rel_p 1 489 1.1 christos #define elf_backend_may_use_rela_p 0 490 1.1 christos #define elf_backend_default_use_rela_p 0 491 1.1 christos #define elf_backend_relocate_section bpf_elf_relocate_section 492 1.1 christos 493 1.1 christos #define elf_backend_can_gc_sections 0 494 1.1 christos 495 1.1 christos #define elf_symbol_leading_char '_' 496 1.1 christos #define bfd_elf64_bfd_reloc_type_lookup bpf_reloc_type_lookup 497 1.1 christos #define bfd_elf64_bfd_reloc_name_lookup bpf_reloc_name_lookup 498 1.1 christos 499 1.1 christos #define bfd_elf64_bfd_merge_private_bfd_data elf64_bpf_merge_private_bfd_data 500 1.1 christos 501 1.1 christos #include "elf64-target.h" 502