xref: /netbsd-src/external/gpl3/gdb/dist/bfd/wasm-module.c (revision ccd9df534e375a4366c5b55f23782053c7a98d82)
1 /* BFD back-end for WebAssembly modules.
2    Copyright (C) 2017-2022 Free Software Foundation, Inc.
3 
4    Based on srec.c, mmo.c, and binary.c
5 
6    This file is part of BFD, the Binary File Descriptor library.
7 
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21    MA 02110-1301, USA.  */
22 
23 /* The WebAssembly module format is a simple object file format
24    including up to 11 numbered sections, plus any number of named
25    "custom" sections. It is described at:
26    https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md. */
27 
28 #include "sysdep.h"
29 #include "bfd.h"
30 #include "libiberty.h"
31 #include "libbfd.h"
32 #include "wasm-module.h"
33 
34 #include <limits.h>
35 #ifndef CHAR_BIT
36 #define CHAR_BIT 8
37 #endif
38 
39 typedef struct
40 {
41   asymbol *      symbols;
42   bfd_size_type  symcount;
43 } tdata_type;
44 
45 static const char * const wasm_numbered_sections[] =
46 {
47   NULL, /* Custom section, different layout.  */
48   WASM_SECTION ( 1, "type"),
49   WASM_SECTION ( 2, "import"),
50   WASM_SECTION ( 3, "function"),
51   WASM_SECTION ( 4, "table"),
52   WASM_SECTION ( 5, "memory"),
53   WASM_SECTION ( 6, "global"),
54   WASM_SECTION ( 7, "export"),
55   WASM_SECTION ( 8, "start"),
56   WASM_SECTION ( 9, "element"),
57   WASM_SECTION (10, "code"),
58   WASM_SECTION (11, "data"),
59 };
60 
61 #define WASM_NUMBERED_SECTIONS ARRAY_SIZE (wasm_numbered_sections)
62 
63 /* Resolve SECTION_CODE to a section name if there is one, NULL
64    otherwise.  */
65 
66 static const char *
67 wasm_section_code_to_name (bfd_byte section_code)
68 {
69   if (section_code < WASM_NUMBERED_SECTIONS)
70     return wasm_numbered_sections[section_code];
71 
72   return NULL;
73 }
74 
75 /* Translate section name NAME to a section code, or 0 if it's a
76    custom name.  */
77 
78 static unsigned int
79 wasm_section_name_to_code (const char *name)
80 {
81   unsigned i;
82 
83   for (i = 1; i < WASM_NUMBERED_SECTIONS; i++)
84     if (strcmp (name, wasm_numbered_sections[i]) == 0)
85       return i;
86 
87   return 0;
88 }
89 
90 /* WebAssembly LEB128 integers are sufficiently like DWARF LEB128
91    integers that we use _bfd_safe_read_leb128, but there are two
92    points of difference:
93 
94    - WebAssembly requires a 32-bit value to be encoded in at most 5
95      bytes, etc.
96    - _bfd_safe_read_leb128 accepts incomplete LEB128 encodings at the
97      end of the buffer, while these are invalid in WebAssembly.
98 
99    Those differences mean that we will accept some files that are
100    invalid WebAssembly.  */
101 
102 /* Read an LEB128-encoded integer from ABFD's I/O stream, reading one
103    byte at a time.  Set ERROR_RETURN if no complete integer could be
104    read, LENGTH_RETURN to the number of bytes read (including bytes in
105    incomplete numbers).  SIGN means interpret the number as SLEB128. */
106 
107 static bfd_vma
108 wasm_read_leb128 (bfd *abfd,
109 		  bool *error_return,
110 		  unsigned int *length_return,
111 		  bool sign)
112 {
113   bfd_vma result = 0;
114   unsigned int num_read = 0;
115   unsigned int shift = 0;
116   unsigned char byte = 0;
117   unsigned char lost, mask;
118   int status = 1;
119 
120   while (bfd_bread (&byte, 1, abfd) == 1)
121     {
122       num_read++;
123 
124       if (shift < CHAR_BIT * sizeof (result))
125 	{
126 	  result |= ((bfd_vma) (byte & 0x7f)) << shift;
127 	  /* These bits overflowed.  */
128 	  lost = byte ^ (result >> shift);
129 	  /* And this is the mask of possible overflow bits.  */
130 	  mask = 0x7f ^ ((bfd_vma) 0x7f << shift >> shift);
131 	  shift += 7;
132 	}
133       else
134 	{
135 	  lost = byte;
136 	  mask = 0x7f;
137 	}
138       if ((lost & mask) != (sign && (bfd_signed_vma) result < 0 ? mask : 0))
139 	status |= 2;
140 
141       if ((byte & 0x80) == 0)
142 	{
143 	  status &= ~1;
144 	  if (sign && shift < CHAR_BIT * sizeof (result) && (byte & 0x40))
145 	    result |= -((bfd_vma) 1 << shift);
146 	  break;
147 	}
148     }
149 
150   if (length_return != NULL)
151     *length_return = num_read;
152   if (error_return != NULL)
153     *error_return = status != 0;
154 
155   return result;
156 }
157 
158 /* Encode an integer V as LEB128 and write it to ABFD, return TRUE on
159    success.  */
160 
161 static bool
162 wasm_write_uleb128 (bfd *abfd, bfd_vma v)
163 {
164   do
165     {
166       bfd_byte c = v & 0x7f;
167       v >>= 7;
168 
169       if (v)
170 	c |= 0x80;
171 
172       if (bfd_bwrite (&c, 1, abfd) != 1)
173 	return false;
174     }
175   while (v);
176 
177   return true;
178 }
179 
180 /* Read the LEB128 integer at P, saving it to X; at end of buffer,
181    jump to error_return.  */
182 #define READ_LEB128(x, p, end)						\
183   do									\
184     {									\
185       if ((p) >= (end))							\
186 	goto error_return;						\
187       (x) = _bfd_safe_read_leb128 (abfd, &(p), false, (end));		\
188     }									\
189   while (0)
190 
191 /* Verify the magic number at the beginning of a WebAssembly module
192    ABFD, setting ERRORPTR if there's a mismatch.  */
193 
194 static bool
195 wasm_read_magic (bfd *abfd, bool *errorptr)
196 {
197   bfd_byte magic_const[SIZEOF_WASM_MAGIC] = WASM_MAGIC;
198   bfd_byte magic[SIZEOF_WASM_MAGIC];
199 
200   if (bfd_bread (magic, sizeof (magic), abfd) == sizeof (magic)
201       && memcmp (magic, magic_const, sizeof (magic)) == 0)
202     return true;
203 
204   *errorptr = true;
205   return false;
206 }
207 
208 /* Read the version number from ABFD, returning TRUE if it's a supported
209    version. Set ERRORPTR otherwise.  */
210 
211 static bool
212 wasm_read_version (bfd *abfd, bool *errorptr)
213 {
214   bfd_byte vers_const[SIZEOF_WASM_VERSION] = WASM_VERSION;
215   bfd_byte vers[SIZEOF_WASM_VERSION];
216 
217   if (bfd_bread (vers, sizeof (vers), abfd) == sizeof (vers)
218       /* Don't attempt to parse newer versions, which are likely to
219 	 require code changes.  */
220       && memcmp (vers, vers_const, sizeof (vers)) == 0)
221     return true;
222 
223   *errorptr = true;
224   return false;
225 }
226 
227 /* Read the WebAssembly header (magic number plus version number) from
228    ABFD, setting ERRORPTR to TRUE if there is a mismatch.  */
229 
230 static bool
231 wasm_read_header (bfd *abfd, bool *errorptr)
232 {
233   if (! wasm_read_magic (abfd, errorptr))
234     return false;
235 
236   if (! wasm_read_version (abfd, errorptr))
237     return false;
238 
239   return true;
240 }
241 
242 /* Scan the "function" subsection of the "name" section ASECT in the
243    wasm module ABFD. Create symbols. Return TRUE on success.  */
244 
245 static bool
246 wasm_scan_name_function_section (bfd *abfd, sec_ptr asect)
247 {
248   bfd_byte *p;
249   bfd_byte *end;
250   bfd_vma payload_size;
251   bfd_vma symcount = 0;
252   tdata_type *tdata = abfd->tdata.any;
253   asymbol *symbols = NULL;
254   sec_ptr space_function_index;
255   size_t amt;
256 
257   p = asect->contents;
258   end = asect->contents + asect->size;
259 
260   if (!p)
261     return false;
262 
263   while (p < end)
264     {
265       bfd_byte subsection_code = *p++;
266       if (subsection_code == WASM_FUNCTION_SUBSECTION)
267 	break;
268 
269       /* subsection_code is documented to be a varuint7, meaning that
270 	 it has to be a single byte in the 0 - 127 range.  If it isn't,
271 	 the spec must have changed underneath us, so give up.  */
272       if (subsection_code & 0x80)
273 	return false;
274 
275       READ_LEB128 (payload_size, p, end);
276 
277       if (payload_size > (size_t) (end - p))
278 	return false;
279 
280       p += payload_size;
281     }
282 
283   if (p >= end)
284     return false;
285 
286   READ_LEB128 (payload_size, p, end);
287 
288   if (payload_size > (size_t) (end - p))
289     return false;
290 
291   end = p + payload_size;
292 
293   READ_LEB128 (symcount, p, end);
294 
295   /* Sanity check: each symbol has at least two bytes.  */
296   if (symcount > payload_size / 2)
297     return false;
298 
299   tdata->symcount = symcount;
300 
301   space_function_index
302     = bfd_make_section_with_flags (abfd, WASM_SECTION_FUNCTION_INDEX,
303 				   SEC_READONLY | SEC_CODE);
304 
305   if (!space_function_index)
306     space_function_index
307       = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX);
308 
309   if (!space_function_index)
310     return false;
311 
312   if (_bfd_mul_overflow (tdata->symcount, sizeof (asymbol), &amt))
313     {
314       bfd_set_error (bfd_error_file_too_big);
315       return false;
316     }
317   symbols = bfd_alloc (abfd, amt);
318   if (!symbols)
319     return false;
320 
321   for (symcount = 0; p < end && symcount < tdata->symcount; symcount++)
322     {
323       bfd_vma idx;
324       bfd_vma len;
325       char *name;
326       asymbol *sym;
327 
328       READ_LEB128 (idx, p, end);
329       READ_LEB128 (len, p, end);
330 
331       if (len > (size_t) (end - p))
332 	goto error_return;
333 
334       name = bfd_alloc (abfd, len + 1);
335       if (!name)
336 	goto error_return;
337 
338       memcpy (name, p, len);
339       name[len] = 0;
340       p += len;
341 
342       sym = &symbols[symcount];
343       sym->the_bfd = abfd;
344       sym->name = name;
345       sym->value = idx;
346       sym->flags = BSF_GLOBAL | BSF_FUNCTION;
347       sym->section = space_function_index;
348       sym->udata.p = NULL;
349     }
350 
351   if (symcount < tdata->symcount)
352     goto error_return;
353 
354   tdata->symbols = symbols;
355   abfd->symcount = symcount;
356 
357   return true;
358 
359  error_return:
360   if (symbols)
361     bfd_release (abfd, symbols);
362   tdata->symcount = 0;
363   return false;
364 }
365 
366 /* Read a byte from ABFD and return it, or EOF for EOF or error.
367    Set ERRORPTR on non-EOF error.  */
368 
369 static int
370 wasm_read_byte (bfd *abfd, bool *errorptr)
371 {
372   bfd_byte byte;
373 
374   if (bfd_bread (&byte, (bfd_size_type) 1, abfd) != 1)
375     {
376       if (bfd_get_error () != bfd_error_file_truncated)
377 	*errorptr = true;
378       return EOF;
379     }
380 
381   return byte;
382 }
383 
384 /* Scan the wasm module ABFD, creating sections and symbols.
385    Return TRUE on success.  */
386 
387 static bool
388 wasm_scan (bfd *abfd)
389 {
390   bool error = false;
391   /* Fake VMAs for now. Choose 0x80000000 as base to avoid clashes
392      with actual data addresses.  */
393   bfd_vma vma = 0x80000000;
394   int section_code;
395   unsigned int bytes_read;
396   asection *bfdsec;
397 
398   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
399     goto error_return;
400 
401   if (!wasm_read_header (abfd, &error))
402     goto error_return;
403 
404   while ((section_code = wasm_read_byte (abfd, &error)) != EOF)
405     {
406       if (section_code != 0)
407 	{
408 	  const char *sname = wasm_section_code_to_name (section_code);
409 
410 	  if (!sname)
411 	    goto error_return;
412 
413 	  bfdsec = bfd_make_section_anyway_with_flags (abfd, sname,
414 						       SEC_HAS_CONTENTS);
415 	  if (bfdsec == NULL)
416 	    goto error_return;
417 
418 	  bfdsec->size = wasm_read_leb128 (abfd, &error, &bytes_read, false);
419 	  if (error)
420 	    goto error_return;
421 	}
422       else
423 	{
424 	  bfd_vma payload_len;
425 	  bfd_vma namelen;
426 	  char *name;
427 	  char *prefix = WASM_SECTION_PREFIX;
428 	  size_t prefixlen = strlen (prefix);
429 	  ufile_ptr filesize;
430 
431 	  payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, false);
432 	  if (error)
433 	    goto error_return;
434 	  namelen = wasm_read_leb128 (abfd, &error, &bytes_read, false);
435 	  if (error || bytes_read > payload_len
436 	      || namelen > payload_len - bytes_read)
437 	    goto error_return;
438 	  payload_len -= namelen + bytes_read;
439 	  filesize = bfd_get_file_size (abfd);
440 	  if (filesize != 0 && namelen > filesize)
441 	    {
442 	      bfd_set_error (bfd_error_file_truncated);
443 	      return false;
444 	    }
445 	  name = bfd_alloc (abfd, namelen + prefixlen + 1);
446 	  if (!name)
447 	    goto error_return;
448 	  memcpy (name, prefix, prefixlen);
449 	  if (bfd_bread (name + prefixlen, namelen, abfd) != namelen)
450 	    goto error_return;
451 	  name[prefixlen + namelen] = 0;
452 
453 	  bfdsec = bfd_make_section_anyway_with_flags (abfd, name,
454 						       SEC_HAS_CONTENTS);
455 	  if (bfdsec == NULL)
456 	    goto error_return;
457 
458 	  bfdsec->size = payload_len;
459 	}
460 
461       bfdsec->vma = vma;
462       bfdsec->lma = vma;
463       bfdsec->alignment_power = 0;
464       bfdsec->filepos = bfd_tell (abfd);
465       if (bfdsec->size != 0)
466 	{
467 	  bfdsec->contents = _bfd_alloc_and_read (abfd, bfdsec->size,
468 						  bfdsec->size);
469 	  if (!bfdsec->contents)
470 	    goto error_return;
471 	}
472 
473       vma += bfdsec->size;
474     }
475 
476   /* Make sure we're at actual EOF.  There's no indication in the
477      WebAssembly format of how long the file is supposed to be.  */
478   if (error)
479     goto error_return;
480 
481   return true;
482 
483  error_return:
484   return false;
485 }
486 
487 /* Put a numbered section ASECT of ABFD into the table of numbered
488    sections pointed to by FSARG.  */
489 
490 static void
491 wasm_register_section (bfd *abfd ATTRIBUTE_UNUSED,
492 		       asection *asect,
493 		       void *fsarg)
494 {
495   sec_ptr *numbered_sections = fsarg;
496   int idx = wasm_section_name_to_code (asect->name);
497 
498   if (idx == 0)
499     return;
500 
501   numbered_sections[idx] = asect;
502 }
503 
504 struct compute_section_arg
505 {
506   bfd_vma pos;
507   bool failed;
508 };
509 
510 /* Compute the file position of ABFD's section ASECT.  FSARG is a
511    pointer to the current file position.
512 
513    We allow section names of the form .wasm.id to encode the numbered
514    section with ID id, if it exists; otherwise, a custom section with
515    ID "id" is produced.  Arbitrary section names are for sections that
516    are assumed already to contain a section header; those are appended
517    to the WebAssembly module verbatim.  */
518 
519 static void
520 wasm_compute_custom_section_file_position (bfd *abfd,
521 					   sec_ptr asect,
522 					   void *fsarg)
523 {
524   struct compute_section_arg *fs = fsarg;
525   int idx;
526 
527   if (fs->failed)
528     return;
529 
530   idx = wasm_section_name_to_code (asect->name);
531 
532   if (idx != 0)
533     return;
534 
535   if (startswith (asect->name, WASM_SECTION_PREFIX))
536     {
537       const char *name = asect->name + strlen (WASM_SECTION_PREFIX);
538       bfd_size_type payload_len = asect->size;
539       bfd_size_type name_len = strlen (name);
540       bfd_size_type nl = name_len;
541 
542       payload_len += name_len;
543 
544       do
545 	{
546 	  payload_len++;
547 	  nl >>= 7;
548 	}
549       while (nl);
550 
551       bfd_seek (abfd, fs->pos, SEEK_SET);
552       if (! wasm_write_uleb128 (abfd, 0)
553 	  || ! wasm_write_uleb128 (abfd, payload_len)
554 	  || ! wasm_write_uleb128 (abfd, name_len)
555 	  || bfd_bwrite (name, name_len, abfd) != name_len)
556 	goto error_return;
557       fs->pos = asect->filepos = bfd_tell (abfd);
558     }
559   else
560     {
561       asect->filepos = fs->pos;
562     }
563 
564 
565   fs->pos += asect->size;
566   return;
567 
568  error_return:
569   fs->failed = true;
570 }
571 
572 /* Compute the file positions for the sections of ABFD.  Currently,
573    this writes all numbered sections first, in order, then all custom
574    sections, in section order.
575 
576    The spec says that the numbered sections must appear in order of
577    their ids, but custom sections can appear in any position and any
578    order, and more than once. FIXME: support that.  */
579 
580 static bool
581 wasm_compute_section_file_positions (bfd *abfd)
582 {
583   bfd_byte magic[SIZEOF_WASM_MAGIC] = WASM_MAGIC;
584   bfd_byte vers[SIZEOF_WASM_VERSION] = WASM_VERSION;
585   sec_ptr numbered_sections[WASM_NUMBERED_SECTIONS];
586   struct compute_section_arg fs;
587   unsigned int i;
588 
589   bfd_seek (abfd, (bfd_vma) 0, SEEK_SET);
590 
591   if (bfd_bwrite (magic, sizeof (magic), abfd) != (sizeof magic)
592       || bfd_bwrite (vers, sizeof (vers), abfd) != sizeof (vers))
593     return false;
594 
595   for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
596     numbered_sections[i] = NULL;
597 
598   bfd_map_over_sections (abfd, wasm_register_section, numbered_sections);
599 
600   fs.pos = bfd_tell (abfd);
601   for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
602     {
603       sec_ptr sec = numbered_sections[i];
604       bfd_size_type size;
605 
606       if (! sec)
607 	continue;
608       size = sec->size;
609       if (bfd_seek (abfd, fs.pos, SEEK_SET) != 0)
610 	return false;
611       if (! wasm_write_uleb128 (abfd, i)
612 	  || ! wasm_write_uleb128 (abfd, size))
613 	return false;
614       fs.pos = sec->filepos = bfd_tell (abfd);
615       fs.pos += size;
616     }
617 
618   fs.failed = false;
619 
620   bfd_map_over_sections (abfd, wasm_compute_custom_section_file_position, &fs);
621 
622   if (fs.failed)
623     return false;
624 
625   abfd->output_has_begun = true;
626 
627   return true;
628 }
629 
630 static bool
631 wasm_set_section_contents (bfd *abfd,
632 			   sec_ptr section,
633 			   const void *location,
634 			   file_ptr offset,
635 			   bfd_size_type count)
636 {
637   if (count == 0)
638     return true;
639 
640   if (! abfd->output_has_begun
641       && ! wasm_compute_section_file_positions (abfd))
642     return false;
643 
644   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
645       || bfd_bwrite (location, count, abfd) != count)
646     return false;
647 
648   return true;
649 }
650 
651 static bool
652 wasm_write_object_contents (bfd* abfd)
653 {
654   bfd_byte magic[] = WASM_MAGIC;
655   bfd_byte vers[] = WASM_VERSION;
656 
657   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
658     return false;
659 
660   if (bfd_bwrite (magic, sizeof (magic), abfd) != sizeof (magic)
661       || bfd_bwrite (vers, sizeof (vers), abfd) != sizeof (vers))
662     return false;
663 
664   return true;
665 }
666 
667 static bool
668 wasm_mkobject (bfd *abfd)
669 {
670   tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
671 
672   if (! tdata)
673     return false;
674 
675   tdata->symbols = NULL;
676   tdata->symcount = 0;
677 
678   abfd->tdata.any = tdata;
679 
680   return true;
681 }
682 
683 static long
684 wasm_get_symtab_upper_bound (bfd *abfd)
685 {
686   tdata_type *tdata = abfd->tdata.any;
687 
688   return (tdata->symcount + 1) * (sizeof (asymbol *));
689 }
690 
691 static long
692 wasm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
693 {
694   tdata_type *tdata = abfd->tdata.any;
695   size_t i;
696 
697   for (i = 0; i < tdata->symcount; i++)
698     alocation[i] = &tdata->symbols[i];
699   alocation[i] = NULL;
700 
701   return tdata->symcount;
702 }
703 
704 static asymbol *
705 wasm_make_empty_symbol (bfd *abfd)
706 {
707   size_t amt = sizeof (asymbol);
708   asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
709 
710   if (! new_symbol)
711     return NULL;
712   new_symbol->the_bfd = abfd;
713   return new_symbol;
714 }
715 
716 static void
717 wasm_print_symbol (bfd *abfd,
718 		   void * filep,
719 		   asymbol *symbol,
720 		   bfd_print_symbol_type how)
721 {
722   FILE *file = (FILE *) filep;
723 
724   switch (how)
725     {
726     case bfd_print_symbol_name:
727       fprintf (file, "%s", symbol->name);
728       break;
729 
730     default:
731       bfd_print_symbol_vandf (abfd, filep, symbol);
732       fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
733     }
734 }
735 
736 static void
737 wasm_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
738 		      asymbol *symbol,
739 		      symbol_info *ret)
740 {
741   bfd_symbol_info (symbol, ret);
742 }
743 
744 /* Check whether ABFD is a WebAssembly module; if so, scan it.  */
745 
746 static bfd_cleanup
747 wasm_object_p (bfd *abfd)
748 {
749   bool error;
750   asection *s;
751 
752   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0)
753     return NULL;
754 
755   if (!wasm_read_header (abfd, &error))
756     {
757       bfd_set_error (bfd_error_wrong_format);
758       return NULL;
759     }
760 
761   if (!wasm_mkobject (abfd))
762     return NULL;
763 
764   if (!wasm_scan (abfd)
765       || !bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
766     {
767       bfd_release (abfd, abfd->tdata.any);
768       abfd->tdata.any = NULL;
769       return NULL;
770     }
771 
772   s = bfd_get_section_by_name (abfd, WASM_NAME_SECTION);
773   if (s != NULL && wasm_scan_name_function_section (abfd, s))
774     abfd->flags |= HAS_SYMS;
775 
776   return _bfd_no_cleanup;
777 }
778 
779 /* BFD_JUMP_TABLE_WRITE */
780 #define wasm_set_arch_mach		  _bfd_generic_set_arch_mach
781 
782 /* BFD_JUMP_TABLE_SYMBOLS */
783 #define wasm_get_symbol_version_string	  _bfd_nosymbols_get_symbol_version_string
784 #define wasm_bfd_is_local_label_name	   bfd_generic_is_local_label_name
785 #define wasm_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
786 #define wasm_get_lineno			  _bfd_nosymbols_get_lineno
787 #define wasm_find_nearest_line		  _bfd_nosymbols_find_nearest_line
788 #define wasm_find_nearest_line_with_alt	  _bfd_nosymbols_find_nearest_line_with_alt
789 #define wasm_find_line			  _bfd_nosymbols_find_line
790 #define wasm_find_inliner_info		  _bfd_nosymbols_find_inliner_info
791 #define wasm_bfd_make_debug_symbol	  _bfd_nosymbols_bfd_make_debug_symbol
792 #define wasm_read_minisymbols		  _bfd_generic_read_minisymbols
793 #define wasm_minisymbol_to_symbol	  _bfd_generic_minisymbol_to_symbol
794 
795 const bfd_target wasm_vec =
796 {
797   "wasm",			/* Name.  */
798   bfd_target_unknown_flavour,
799   BFD_ENDIAN_LITTLE,
800   BFD_ENDIAN_LITTLE,
801   (HAS_SYMS | WP_TEXT),		/* Object flags.  */
802   (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS), /* Section flags.  */
803   0,				/* Leading underscore.  */
804   ' ',				/* AR_pad_char.  */
805   255,				/* AR_max_namelen.  */
806   0,				/* Match priority.  */
807   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
808   /* Routines to byte-swap various sized integers from the data sections.  */
809   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
810   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
811   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
812 
813   /* Routines to byte-swap various sized integers from the file headers.  */
814   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
815   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
816   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
817 
818   {
819     _bfd_dummy_target,
820     wasm_object_p,		/* bfd_check_format.  */
821     _bfd_dummy_target,
822     _bfd_dummy_target,
823   },
824   {
825     _bfd_bool_bfd_false_error,
826     wasm_mkobject,
827     _bfd_generic_mkarchive,
828     _bfd_bool_bfd_false_error,
829   },
830   {				/* bfd_write_contents.  */
831     _bfd_bool_bfd_false_error,
832     wasm_write_object_contents,
833     _bfd_write_archive_contents,
834     _bfd_bool_bfd_false_error,
835   },
836 
837   BFD_JUMP_TABLE_GENERIC (_bfd_generic),
838   BFD_JUMP_TABLE_COPY (_bfd_generic),
839   BFD_JUMP_TABLE_CORE (_bfd_nocore),
840   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
841   BFD_JUMP_TABLE_SYMBOLS (wasm),
842   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
843   BFD_JUMP_TABLE_WRITE (wasm),
844   BFD_JUMP_TABLE_LINK (_bfd_nolink),
845   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
846 
847   NULL,
848 
849   NULL,
850 };
851