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