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