elf64-bpf.c revision 1.1.1.3 1 1.1 christos /* Linux bpf specific support for 64-bit ELF
2 1.1.1.3 christos Copyright (C) 2019-2024 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 christos rel, 1, relend, howto, 0, contents);
245 1.1 christos
246 1.1 christos if (bfd_link_relocatable (info))
247 1.1 christos continue;
248 1.1 christos
249 1.1 christos switch (howto->type)
250 1.1 christos {
251 1.1.1.3 christos case R_BPF_64_32:
252 1.1 christos {
253 1.1 christos /* Make the relocation PC-relative, and change its unit to
254 1.1.1.2 christos 64-bit words. Note we need *signed* arithmetic
255 1.1.1.2 christos here. */
256 1.1.1.2 christos relocation = ((bfd_signed_vma) relocation
257 1.1.1.2 christos - (sec_addr (input_section) + rel->r_offset));
258 1.1.1.2 christos relocation = (bfd_signed_vma) relocation / 8;
259 1.1 christos
260 1.1 christos /* Get the addend from the instruction and apply it. */
261 1.1 christos addend = bfd_get (howto->bitsize, input_bfd,
262 1.1 christos contents + rel->r_offset
263 1.1 christos + (howto->bitsize == 16 ? 2 : 4));
264 1.1 christos
265 1.1 christos if ((addend & (((~howto->src_mask) >> 1) & howto->src_mask)) != 0)
266 1.1 christos addend -= (((~howto->src_mask) >> 1) & howto->src_mask) << 1;
267 1.1 christos relocation += addend;
268 1.1 christos
269 1.1 christos /* Write out the relocated value. */
270 1.1 christos bfd_put (howto->bitsize, input_bfd, relocation,
271 1.1 christos contents + rel->r_offset
272 1.1 christos + (howto->bitsize == 16 ? 2 : 4));
273 1.1 christos
274 1.1 christos r = bfd_reloc_ok;
275 1.1 christos break;
276 1.1 christos }
277 1.1.1.3 christos case R_BPF_64_ABS64:
278 1.1.1.3 christos case R_BPF_64_ABS32:
279 1.1.1.3 christos case R_BPF_64_NODYLD32:
280 1.1.1.2 christos {
281 1.1.1.2 christos addend = bfd_get (howto->bitsize, input_bfd, where);
282 1.1.1.2 christos relocation += addend;
283 1.1.1.2 christos bfd_put (howto->bitsize, input_bfd, relocation, where);
284 1.1.1.2 christos
285 1.1.1.2 christos r = bfd_reloc_ok;
286 1.1.1.2 christos break;
287 1.1.1.2 christos }
288 1.1.1.3 christos case R_BPF_64_64:
289 1.1.1.2 christos {
290 1.1.1.2 christos /*
291 1.1.1.2 christos LDDW instructions are 128 bits long, with a 64-bit immediate.
292 1.1.1.2 christos The lower 32 bits of the immediate are in the same position
293 1.1.1.2 christos as the imm32 field of other instructions.
294 1.1.1.2 christos The upper 32 bits of the immediate are stored at the end of
295 1.1.1.2 christos the instruction.
296 1.1.1.2 christos */
297 1.1.1.2 christos
298 1.1.1.2 christos
299 1.1.1.2 christos /* Get the addend. The upper and lower 32 bits are split.
300 1.1.1.2 christos 'where' is the beginning of the 16-byte instruction. */
301 1.1.1.2 christos addend = bfd_get_32 (input_bfd, where + 4);
302 1.1.1.2 christos addend |= (bfd_get_32 (input_bfd, where + 12) << 32);
303 1.1.1.2 christos
304 1.1.1.2 christos relocation += addend;
305 1.1.1.2 christos
306 1.1.1.2 christos bfd_put_32 (input_bfd, (relocation & 0xFFFFFFFF), where + 4);
307 1.1.1.2 christos bfd_put_32 (input_bfd, (relocation >> 32), where + 12);
308 1.1.1.2 christos r = bfd_reloc_ok;
309 1.1.1.2 christos break;
310 1.1.1.2 christos }
311 1.1 christos default:
312 1.1.1.2 christos r = bfd_reloc_notsupported;
313 1.1 christos }
314 1.1 christos
315 1.1.1.2 christos if (r == bfd_reloc_ok)
316 1.1.1.2 christos r = bfd_check_overflow (howto->complain_on_overflow,
317 1.1.1.2 christos howto->bitsize,
318 1.1.1.2 christos howto->rightshift,
319 1.1.1.2 christos 64, relocation);
320 1.1.1.2 christos
321 1.1 christos if (r != bfd_reloc_ok)
322 1.1 christos {
323 1.1 christos const char * msg = NULL;
324 1.1 christos
325 1.1 christos switch (r)
326 1.1 christos {
327 1.1 christos case bfd_reloc_overflow:
328 1.1 christos (*info->callbacks->reloc_overflow)
329 1.1 christos (info, (h ? &h->root : NULL), name, howto->name,
330 1.1 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
331 1.1 christos break;
332 1.1 christos
333 1.1 christos case bfd_reloc_undefined:
334 1.1 christos (*info->callbacks->undefined_symbol)
335 1.1.1.2 christos (info, name, input_bfd, input_section, rel->r_offset, true);
336 1.1 christos break;
337 1.1 christos
338 1.1 christos case bfd_reloc_outofrange:
339 1.1 christos msg = _("internal error: out of range error");
340 1.1 christos break;
341 1.1 christos
342 1.1 christos case bfd_reloc_notsupported:
343 1.1 christos if (sym != NULL) /* Only if it's not an unresolved symbol. */
344 1.1 christos msg = _("internal error: relocation not supported");
345 1.1 christos break;
346 1.1 christos
347 1.1 christos case bfd_reloc_dangerous:
348 1.1 christos msg = _("internal error: dangerous relocation");
349 1.1 christos break;
350 1.1 christos
351 1.1 christos default:
352 1.1 christos msg = _("internal error: unknown error");
353 1.1 christos break;
354 1.1 christos }
355 1.1 christos
356 1.1 christos if (msg)
357 1.1 christos (*info->callbacks->warning) (info, msg, name, input_bfd,
358 1.1 christos input_section, rel->r_offset);
359 1.1 christos }
360 1.1 christos }
361 1.1 christos
362 1.1.1.2 christos return true;
363 1.1 christos }
364 1.1 christos
365 1.1 christos /* Merge backend specific data from an object file to the output
366 1.1 christos object file when linking. */
367 1.1 christos
368 1.1.1.2 christos static bool
369 1.1 christos elf64_bpf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
370 1.1 christos {
371 1.1 christos /* Check if we have the same endianness. */
372 1.1 christos if (! _bfd_generic_verify_endian_match (ibfd, info))
373 1.1.1.2 christos return false;
374 1.1 christos
375 1.1.1.2 christos return true;
376 1.1 christos }
377 1.1 christos
378 1.1.1.2 christos /* A generic howto special function for installing BPF relocations.
379 1.1.1.2 christos This function will be called by the assembler (via bfd_install_relocation),
380 1.1.1.2 christos and by various get_relocated_section_contents functions.
381 1.1.1.2 christos At link time, bpf_elf_relocate_section will resolve the final relocations.
382 1.1.1.2 christos
383 1.1.1.2 christos BPF instructions are always big endian, and this approach avoids problems in
384 1.1.1.2 christos bfd_install_relocation. */
385 1.1.1.2 christos
386 1.1.1.2 christos static bfd_reloc_status_type
387 1.1.1.2 christos bpf_elf_generic_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
388 1.1.1.3 christos void *data, asection *input_section, bfd *output_bfd,
389 1.1.1.2 christos char **error_message ATTRIBUTE_UNUSED)
390 1.1.1.2 christos {
391 1.1.1.2 christos
392 1.1.1.2 christos bfd_signed_vma relocation;
393 1.1.1.2 christos bfd_reloc_status_type status;
394 1.1.1.2 christos bfd_byte *where;
395 1.1.1.2 christos
396 1.1.1.3 christos /* From bfd_elf_generic_reloc. */
397 1.1.1.3 christos if (output_bfd != NULL
398 1.1.1.3 christos && (symbol->flags & BSF_SECTION_SYM) == 0
399 1.1.1.3 christos && (! reloc_entry->howto->partial_inplace
400 1.1.1.3 christos || reloc_entry->addend == 0))
401 1.1.1.3 christos {
402 1.1.1.3 christos reloc_entry->address += input_section->output_offset;
403 1.1.1.3 christos return bfd_reloc_ok;
404 1.1.1.3 christos }
405 1.1.1.3 christos
406 1.1.1.3 christos if (output_bfd == NULL
407 1.1.1.3 christos && !reloc_entry->howto->pc_relative
408 1.1.1.3 christos && (symbol->section->flags & SEC_DEBUGGING) != 0
409 1.1.1.3 christos && (input_section->flags & SEC_DEBUGGING) != 0)
410 1.1.1.3 christos reloc_entry->addend -= symbol->section->output_section->vma;
411 1.1.1.3 christos
412 1.1.1.2 christos /* Sanity check that the address is in range. */
413 1.1.1.2 christos bfd_size_type end = bfd_get_section_limit_octets (abfd, input_section);
414 1.1.1.2 christos bfd_size_type reloc_size;
415 1.1.1.3 christos if (reloc_entry->howto->type == R_BPF_64_64)
416 1.1.1.2 christos reloc_size = 16;
417 1.1.1.2 christos else
418 1.1.1.2 christos reloc_size = (reloc_entry->howto->bitsize
419 1.1.1.2 christos + reloc_entry->howto->bitpos) / 8;
420 1.1.1.2 christos
421 1.1.1.2 christos if (reloc_entry->address > end
422 1.1.1.2 christos || end - reloc_entry->address < reloc_size)
423 1.1.1.2 christos return bfd_reloc_outofrange;
424 1.1.1.2 christos
425 1.1.1.3 christos /* Behave similarly to bfd_install_relocation with install_addend set.
426 1.1.1.3 christos That is, just install the addend and do not include the value of
427 1.1.1.3 christos the symbol. */
428 1.1.1.3 christos relocation = reloc_entry->addend;
429 1.1.1.2 christos
430 1.1.1.2 christos if (symbol->flags & BSF_SECTION_SYM)
431 1.1.1.2 christos /* Relocation against a section symbol: add in the section base address. */
432 1.1.1.2 christos relocation += BASEADDR (symbol->section);
433 1.1.1.2 christos
434 1.1.1.2 christos where = (bfd_byte *) data + reloc_entry->address;
435 1.1.1.2 christos
436 1.1.1.2 christos status = bfd_check_overflow (reloc_entry->howto->complain_on_overflow,
437 1.1.1.2 christos reloc_entry->howto->bitsize,
438 1.1.1.2 christos reloc_entry->howto->rightshift, 64, relocation);
439 1.1.1.2 christos
440 1.1.1.2 christos if (status != bfd_reloc_ok)
441 1.1.1.2 christos return status;
442 1.1.1.2 christos
443 1.1.1.2 christos /* Now finally install the relocation. */
444 1.1.1.3 christos if (reloc_entry->howto->type == R_BPF_64_64)
445 1.1.1.2 christos {
446 1.1.1.2 christos /* lddw is a 128-bit (!) instruction that allows loading a 64-bit
447 1.1.1.2 christos immediate into a register. the immediate is split in half, with the
448 1.1.1.2 christos lower 32 bits in the same position as the imm32 field of other
449 1.1.1.2 christos instructions, and the upper 32 bits placed at the very end of the
450 1.1.1.2 christos instruction. that is, there are 32 unused bits between them. */
451 1.1.1.2 christos
452 1.1.1.2 christos bfd_put_32 (abfd, (relocation & 0xFFFFFFFF), where + 4);
453 1.1.1.2 christos bfd_put_32 (abfd, (relocation >> 32), where + 12);
454 1.1.1.2 christos }
455 1.1.1.2 christos else
456 1.1.1.2 christos {
457 1.1.1.2 christos /* For other kinds of relocations, the relocated value simply goes
458 1.1.1.2 christos BITPOS bits from the start of the entry. This is always a multiple
459 1.1.1.2 christos of 8, i.e. whole bytes. */
460 1.1.1.2 christos bfd_put (reloc_entry->howto->bitsize, abfd, relocation,
461 1.1.1.2 christos where + reloc_entry->howto->bitpos / 8);
462 1.1.1.2 christos }
463 1.1.1.2 christos
464 1.1.1.3 christos if (output_bfd != NULL)
465 1.1.1.3 christos reloc_entry->address += input_section->output_offset;
466 1.1.1.2 christos
467 1.1.1.2 christos return bfd_reloc_ok;
468 1.1.1.2 christos }
469 1.1.1.2 christos
470 1.1.1.2 christos
471 1.1 christos /* The macros below configure the architecture. */
472 1.1 christos
473 1.1 christos #define TARGET_LITTLE_SYM bpf_elf64_le_vec
474 1.1 christos #define TARGET_LITTLE_NAME "elf64-bpfle"
475 1.1 christos
476 1.1 christos #define TARGET_BIG_SYM bpf_elf64_be_vec
477 1.1 christos #define TARGET_BIG_NAME "elf64-bpfbe"
478 1.1 christos
479 1.1 christos #define ELF_ARCH bfd_arch_bpf
480 1.1 christos #define ELF_MACHINE_CODE EM_BPF
481 1.1 christos
482 1.1 christos #define ELF_MAXPAGESIZE 0x100000
483 1.1 christos
484 1.1 christos #define elf_info_to_howto_rel bpf_info_to_howto
485 1.1 christos #define elf_info_to_howto bpf_info_to_howto
486 1.1 christos
487 1.1 christos #define elf_backend_may_use_rel_p 1
488 1.1 christos #define elf_backend_may_use_rela_p 0
489 1.1 christos #define elf_backend_default_use_rela_p 0
490 1.1 christos #define elf_backend_relocate_section bpf_elf_relocate_section
491 1.1 christos
492 1.1 christos #define elf_backend_can_gc_sections 0
493 1.1 christos
494 1.1 christos #define elf_symbol_leading_char '_'
495 1.1 christos #define bfd_elf64_bfd_reloc_type_lookup bpf_reloc_type_lookup
496 1.1 christos #define bfd_elf64_bfd_reloc_name_lookup bpf_reloc_name_lookup
497 1.1 christos
498 1.1 christos #define bfd_elf64_bfd_merge_private_bfd_data elf64_bpf_merge_private_bfd_data
499 1.1 christos
500 1.1 christos #include "elf64-target.h"
501