X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fwasm-module.c;h=66ac2d1874b5bcb71d584772868b95d40cc5b689;hb=1f7f2abbc31ee9e6d4faca58bef14d8ee8cb1bd2;hp=06a964c12df1738206febba3af7dd67ee82bb722;hpb=b3adc24a0713411ab38a21dc894dd40dbc5c8f4f;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/wasm-module.c b/bfd/wasm-module.c index 06a964c12d..66ac2d1874 100644 --- a/bfd/wasm-module.c +++ b/bfd/wasm-module.c @@ -245,17 +245,12 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) tdata_type *tdata = abfd->tdata.any; asymbol *symbols = NULL; sec_ptr space_function_index; - - if (! asect) - return FALSE; - - if (strcmp (asect->name, WASM_NAME_SECTION) != 0) - return FALSE; + size_t amt; p = asect->contents; end = asect->contents + asect->size; - if (! p) + if (!p) return FALSE; while (p < end) @@ -272,7 +267,7 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) READ_LEB128 (payload_size, p, end); - if (p > p + payload_size) + if (payload_size > (size_t) (end - p)) return FALSE; p += payload_size; @@ -283,10 +278,7 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) READ_LEB128 (payload_size, p, end); - if (p > p + payload_size) - return FALSE; - - if (p + payload_size > end) + if (payload_size > (size_t) (end - p)) return FALSE; end = p + payload_size; @@ -294,22 +286,29 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) READ_LEB128 (symcount, p, end); /* Sanity check: each symbol has at least two bytes. */ - if (symcount > payload_size/2) + if (symcount > payload_size / 2) return FALSE; tdata->symcount = symcount; - space_function_index = bfd_make_section_with_flags - (abfd, WASM_SECTION_FUNCTION_INDEX, SEC_READONLY | SEC_CODE); + space_function_index + = bfd_make_section_with_flags (abfd, WASM_SECTION_FUNCTION_INDEX, + SEC_READONLY | SEC_CODE); - if (! space_function_index) - space_function_index = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX); + if (!space_function_index) + space_function_index + = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX); - if (! space_function_index) + if (!space_function_index) return FALSE; - symbols = bfd_zalloc (abfd, tdata->symcount * sizeof (asymbol)); - if (! symbols) + if (_bfd_mul_overflow (tdata->symcount, sizeof (asymbol), &amt)) + { + bfd_set_error (bfd_error_file_too_big); + return FALSE; + } + symbols = bfd_alloc (abfd, amt); + if (!symbols) return FALSE; for (symcount = 0; p < end && symcount < tdata->symcount; symcount++) @@ -322,14 +321,15 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) READ_LEB128 (idx, p, end); READ_LEB128 (len, p, end); - if (p + len < p || p + len > end) + if (len > (size_t) (end - p)) goto error_return; - name = bfd_zalloc (abfd, len + 1); - if (! name) + name = bfd_alloc (abfd, len + 1); + if (!name) goto error_return; memcpy (name, p, len); + name[len] = 0; p += len; sym = &symbols[symcount]; @@ -350,8 +350,6 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) return TRUE; error_return: - while (symcount) - bfd_release (abfd, (void *)symbols[--symcount].name); bfd_release (abfd, symbols); return FALSE; } @@ -386,13 +384,12 @@ wasm_scan (bfd *abfd) bfd_vma vma = 0x80000000; int section_code; unsigned int bytes_read; - char *name = NULL; asection *bfdsec; if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) goto error_return; - if (! wasm_read_header (abfd, &error)) + if (!wasm_read_header (abfd, &error)) goto error_return; while ((section_code = wasm_read_byte (abfd, &error)) != EOF) @@ -401,69 +398,66 @@ wasm_scan (bfd *abfd) { const char *sname = wasm_section_code_to_name (section_code); - if (! sname) + if (!sname) goto error_return; - name = strdup (sname); - bfdsec = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); + bfdsec = bfd_make_section_anyway_with_flags (abfd, sname, + SEC_HAS_CONTENTS); if (bfdsec == NULL) goto error_return; - name = NULL; - bfdsec->vma = vma; - bfdsec->lma = vma; bfdsec->size = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE); if (error) goto error_return; - bfdsec->filepos = bfd_tell (abfd); - bfdsec->alignment_power = 0; } else { bfd_vma payload_len; - file_ptr section_start; bfd_vma namelen; + char *name; char *prefix = WASM_SECTION_PREFIX; - char *p; - int ret; + size_t prefixlen = strlen (prefix); + ufile_ptr filesize; payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE); if (error) goto error_return; - section_start = bfd_tell (abfd); namelen = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE); - if (error || namelen > payload_len) - goto error_return; - name = bfd_zmalloc (namelen + strlen (prefix) + 1); - if (! name) + if (error || bytes_read > payload_len + || namelen > payload_len - bytes_read) goto error_return; - p = name; - ret = sprintf (p, "%s", prefix); - if (ret < 0 || (bfd_vma) ret != strlen (prefix)) + payload_len -= namelen + bytes_read; + filesize = bfd_get_file_size (abfd); + if (filesize != 0 && namelen > filesize) + { + bfd_set_error (bfd_error_file_truncated); + return FALSE; + } + name = bfd_alloc (abfd, namelen + prefixlen + 1); + if (!name) goto error_return; - p += ret; - if (bfd_bread (p, namelen, abfd) != namelen) + memcpy (name, prefix, prefixlen); + if (bfd_bread (name + prefixlen, namelen, abfd) != namelen) goto error_return; + name[prefixlen + namelen] = 0; - bfdsec = bfd_make_section_anyway_with_flags (abfd, name, SEC_HAS_CONTENTS); + bfdsec = bfd_make_section_anyway_with_flags (abfd, name, + SEC_HAS_CONTENTS); if (bfdsec == NULL) goto error_return; - name = NULL; - bfdsec->vma = vma; - bfdsec->lma = vma; - bfdsec->filepos = bfd_tell (abfd); - bfdsec->size = section_start + payload_len - bfdsec->filepos; - bfdsec->alignment_power = 0; + bfdsec->size = payload_len; } + bfdsec->vma = vma; + bfdsec->lma = vma; + bfdsec->alignment_power = 0; + bfdsec->filepos = bfd_tell (abfd); if (bfdsec->size != 0) { - bfdsec->contents = bfd_zalloc (abfd, bfdsec->size); - if (! bfdsec->contents) - goto error_return; - - if (bfd_bread (bfdsec->contents, bfdsec->size, abfd) != bfdsec->size) + bfdsec->contents = _bfd_alloc_and_read (abfd, bfdsec->size, + bfdsec->size); + if (!bfdsec->contents) goto error_return; } @@ -478,12 +472,6 @@ wasm_scan (bfd *abfd) return TRUE; error_return: - if (name) - free (name); - - for (bfdsec = abfd->sections; bfdsec; bfdsec = bfdsec->next) - free ((void *) bfdsec->name); - return FALSE; } @@ -707,7 +695,7 @@ wasm_canonicalize_symtab (bfd *abfd, asymbol **alocation) static asymbol * wasm_make_empty_symbol (bfd *abfd) { - bfd_size_type amt = sizeof (asymbol); + size_t amt = sizeof (asymbol); asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt); if (! new_symbol) @@ -746,30 +734,37 @@ wasm_get_symbol_info (bfd *abfd ATTRIBUTE_UNUSED, /* Check whether ABFD is a WebAssembly module; if so, scan it. */ -static const bfd_target * +static bfd_cleanup wasm_object_p (bfd *abfd) { bfd_boolean error; + asection *s; if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0) return NULL; - if (! wasm_read_header (abfd, &error)) + if (!wasm_read_header (abfd, &error)) { bfd_set_error (bfd_error_wrong_format); return NULL; } - if (! wasm_mkobject (abfd) || ! wasm_scan (abfd)) + if (!wasm_mkobject (abfd)) return NULL; - if (! bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0)) - return NULL; + if (!wasm_scan (abfd) + || !bfd_default_set_arch_mach (abfd, bfd_arch_wasm32, 0)) + { + bfd_release (abfd, abfd->tdata.any); + abfd->tdata.any = NULL; + return NULL; + } - if (wasm_scan_name_function_section (abfd, bfd_get_section_by_name (abfd, WASM_NAME_SECTION))) + s = bfd_get_section_by_name (abfd, WASM_NAME_SECTION); + if (s != NULL && wasm_scan_name_function_section (abfd, s)) abfd->flags |= HAS_SYMS; - return abfd->xvec; + return _bfd_no_cleanup; } /* BFD_JUMP_TABLE_WRITE */