xref: /netbsd-src/external/gpl3/gdb/dist/bfd/wasm-module.c (revision 3117ece4fc4a4ca4489ba793710b60b0d26bab6c)
1 /* BFD back-end for WebAssembly modules.
2    Copyright (C) 2017-2024 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_read (&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_write (&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_read (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_read (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_read (&byte, 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, 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_read (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       if (bfd_seek (abfd, fs->pos, SEEK_SET) != 0
552 	  || ! wasm_write_uleb128 (abfd, 0)
553 	  || ! wasm_write_uleb128 (abfd, payload_len)
554 	  || ! wasm_write_uleb128 (abfd, name_len)
555 	  || bfd_write (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   if (bfd_seek (abfd, (bfd_vma) 0, SEEK_SET) != 0
590       || bfd_write (magic, sizeof (magic), abfd) != (sizeof magic)
591       || bfd_write (vers, sizeof (vers), abfd) != sizeof (vers))
592     return false;
593 
594   for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
595     numbered_sections[i] = NULL;
596 
597   bfd_map_over_sections (abfd, wasm_register_section, numbered_sections);
598 
599   fs.pos = bfd_tell (abfd);
600   for (i = 0; i < WASM_NUMBERED_SECTIONS; i++)
601     {
602       sec_ptr sec = numbered_sections[i];
603       bfd_size_type size;
604 
605       if (! sec)
606 	continue;
607       size = sec->size;
608       if (bfd_seek (abfd, fs.pos, SEEK_SET) != 0)
609 	return false;
610       if (! wasm_write_uleb128 (abfd, i)
611 	  || ! wasm_write_uleb128 (abfd, size))
612 	return false;
613       fs.pos = sec->filepos = bfd_tell (abfd);
614       fs.pos += size;
615     }
616 
617   fs.failed = false;
618 
619   bfd_map_over_sections (abfd, wasm_compute_custom_section_file_position, &fs);
620 
621   if (fs.failed)
622     return false;
623 
624   abfd->output_has_begun = true;
625 
626   return true;
627 }
628 
629 static bool
630 wasm_set_section_contents (bfd *abfd,
631 			   sec_ptr section,
632 			   const void *location,
633 			   file_ptr offset,
634 			   bfd_size_type count)
635 {
636   if (count == 0)
637     return true;
638 
639   if (! abfd->output_has_begun
640       && ! wasm_compute_section_file_positions (abfd))
641     return false;
642 
643   if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
644       || bfd_write (location, count, abfd) != count)
645     return false;
646 
647   return true;
648 }
649 
650 static bool
651 wasm_write_object_contents (bfd* abfd)
652 {
653   bfd_byte magic[] = WASM_MAGIC;
654   bfd_byte vers[] = WASM_VERSION;
655 
656   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
657     return false;
658 
659   if (bfd_write (magic, sizeof (magic), abfd) != sizeof (magic)
660       || bfd_write (vers, sizeof (vers), abfd) != sizeof (vers))
661     return false;
662 
663   return true;
664 }
665 
666 static bool
667 wasm_mkobject (bfd *abfd)
668 {
669   tdata_type *tdata = (tdata_type *) bfd_alloc (abfd, sizeof (tdata_type));
670 
671   if (! tdata)
672     return false;
673 
674   tdata->symbols = NULL;
675   tdata->symcount = 0;
676 
677   abfd->tdata.any = tdata;
678 
679   return true;
680 }
681 
682 static long
683 wasm_get_symtab_upper_bound (bfd *abfd)
684 {
685   tdata_type *tdata = abfd->tdata.any;
686 
687   return (tdata->symcount + 1) * (sizeof (asymbol *));
688 }
689 
690 static long
691 wasm_canonicalize_symtab (bfd *abfd, asymbol **alocation)
692 {
693   tdata_type *tdata = abfd->tdata.any;
694   size_t i;
695 
696   for (i = 0; i < tdata->symcount; i++)
697     alocation[i] = &tdata->symbols[i];
698   alocation[i] = NULL;
699 
700   return tdata->symcount;
701 }
702 
703 static asymbol *
704 wasm_make_empty_symbol (bfd *abfd)
705 {
706   size_t amt = sizeof (asymbol);
707   asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
708 
709   if (! new_symbol)
710     return NULL;
711   new_symbol->the_bfd = abfd;
712   return new_symbol;
713 }
714 
715 static void
716 wasm_print_symbol (bfd *abfd,
717 		   void * filep,
718 		   asymbol *symbol,
719 		   bfd_print_symbol_type how)
720 {
721   FILE *file = (FILE *) filep;
722 
723   switch (how)
724     {
725     case bfd_print_symbol_name:
726       fprintf (file, "%s", symbol->name);
727       break;
728 
729     default:
730       bfd_print_symbol_vandf (abfd, filep, symbol);
731       fprintf (file, " %-5s %s", symbol->section->name, symbol->name);
732     }
733 }
734 
735 static void
736 wasm_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED,
737 		      asymbol *symbol,
738 		      symbol_info *ret)
739 {
740   bfd_symbol_info (symbol, ret);
741 }
742 
743 /* Check whether ABFD is a WebAssembly module; if so, scan it.  */
744 
745 static bfd_cleanup
746 wasm_object_p (bfd *abfd)
747 {
748   bool error;
749   asection *s;
750 
751   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
752     return NULL;
753 
754   if (!wasm_read_header (abfd, &error))
755     {
756       bfd_set_error (bfd_error_wrong_format);
757       return NULL;
758     }
759 
760   if (!wasm_mkobject (abfd))
761     return NULL;
762 
763   if (!wasm_scan (abfd)
764       || !bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0))
765     {
766       bfd_release (abfd, abfd->tdata.any);
767       abfd->tdata.any = NULL;
768       return NULL;
769     }
770 
771   s = bfd_get_section_by_name (abfd, WASM_NAME_SECTION);
772   if (s != NULL && wasm_scan_name_function_section (abfd, s))
773     abfd->flags |= HAS_SYMS;
774 
775   return _bfd_no_cleanup;
776 }
777 
778 /* BFD_JUMP_TABLE_WRITE */
779 #define wasm_set_arch_mach		  _bfd_generic_set_arch_mach
780 
781 /* BFD_JUMP_TABLE_SYMBOLS */
782 #define wasm_get_symbol_version_string	  _bfd_nosymbols_get_symbol_version_string
783 #define wasm_bfd_is_local_label_name	   bfd_generic_is_local_label_name
784 #define wasm_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
785 #define wasm_get_lineno			  _bfd_nosymbols_get_lineno
786 #define wasm_find_nearest_line		  _bfd_nosymbols_find_nearest_line
787 #define wasm_find_nearest_line_with_alt	  _bfd_nosymbols_find_nearest_line_with_alt
788 #define wasm_find_line			  _bfd_nosymbols_find_line
789 #define wasm_find_inliner_info		  _bfd_nosymbols_find_inliner_info
790 #define wasm_bfd_make_debug_symbol	  _bfd_nosymbols_bfd_make_debug_symbol
791 #define wasm_read_minisymbols		  _bfd_generic_read_minisymbols
792 #define wasm_minisymbol_to_symbol	  _bfd_generic_minisymbol_to_symbol
793 
794 const bfd_target wasm_vec =
795 {
796   "wasm",			/* Name.  */
797   bfd_target_unknown_flavour,
798   BFD_ENDIAN_LITTLE,
799   BFD_ENDIAN_LITTLE,
800   (HAS_SYMS | WP_TEXT),		/* Object flags.  */
801   (SEC_CODE | SEC_DATA | SEC_HAS_CONTENTS), /* Section flags.  */
802   0,				/* Leading underscore.  */
803   ' ',				/* AR_pad_char.  */
804   255,				/* AR_max_namelen.  */
805   0,				/* Match priority.  */
806   TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
807   /* Routines to byte-swap various sized integers from the data sections.  */
808   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
809   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
810   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
811 
812   /* Routines to byte-swap various sized integers from the file headers.  */
813   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
814   bfd_getl32, bfd_getl_signed_32, bfd_putl32,
815   bfd_getl16, bfd_getl_signed_16, bfd_putl16,
816 
817   {
818     _bfd_dummy_target,
819     wasm_object_p,		/* bfd_check_format.  */
820     _bfd_dummy_target,
821     _bfd_dummy_target,
822   },
823   {
824     _bfd_bool_bfd_false_error,
825     wasm_mkobject,
826     _bfd_generic_mkarchive,
827     _bfd_bool_bfd_false_error,
828   },
829   {				/* bfd_write_contents.  */
830     _bfd_bool_bfd_false_error,
831     wasm_write_object_contents,
832     _bfd_write_archive_contents,
833     _bfd_bool_bfd_false_error,
834   },
835 
836   BFD_JUMP_TABLE_GENERIC (_bfd_generic),
837   BFD_JUMP_TABLE_COPY (_bfd_generic),
838   BFD_JUMP_TABLE_CORE (_bfd_nocore),
839   BFD_JUMP_TABLE_ARCHIVE (_bfd_noarchive),
840   BFD_JUMP_TABLE_SYMBOLS (wasm),
841   BFD_JUMP_TABLE_RELOCS (_bfd_norelocs),
842   BFD_JUMP_TABLE_WRITE (wasm),
843   BFD_JUMP_TABLE_LINK (_bfd_nolink),
844   BFD_JUMP_TABLE_DYNAMIC (_bfd_nodynamic),
845 
846   NULL,
847 
848   NULL,
849 };
850