X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=bfd%2Fwasm-module.c;h=e62f842e12c07f7f6f6cfa96f884b02d746a6cc5;hb=0c0adcc52478ebb707ed780173e18262df6eab7e;hp=6806e0f81d9c3c6205949b2fe0a527dbcb91800d;hpb=d00dd7dc5e415503de88614bf2ea4aafa2bca819;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/wasm-module.c b/bfd/wasm-module.c index 6806e0f81d..e62f842e12 100644 --- a/bfd/wasm-module.c +++ b/bfd/wasm-module.c @@ -1,5 +1,5 @@ /* BFD back-end for WebAssembly modules. - Copyright (C) 2017-2018 Free Software Foundation, Inc. + Copyright (C) 2017-2020 Free Software Foundation, Inc. Based on srec.c, mmo.c, and binary.c @@ -28,9 +28,7 @@ #include "sysdep.h" #include "alloca-conf.h" #include "bfd.h" -#include "sysdep.h" #include -#include "bfd_stdint.h" #include "libiberty.h" #include "libbfd.h" #include "wasm-module.h" @@ -113,18 +111,28 @@ wasm_read_leb128 (bfd * abfd, unsigned int num_read = 0; unsigned int shift = 0; unsigned char byte = 0; - bfd_boolean success = FALSE; + int status = 1; while (bfd_bread (&byte, 1, abfd) == 1) { num_read++; - result |= ((bfd_vma) (byte & 0x7f)) << shift; + if (shift < sizeof (result) * 8) + { + result |= ((bfd_vma) (byte & 0x7f)) << shift; + if ((result >> shift) != (byte & 0x7f)) + /* Overflow. */ + status |= 2; + shift += 7; + } + else if ((byte & 0x7f) != 0) + status |= 2; - shift += 7; if ((byte & 0x80) == 0) { - success = TRUE; + status &= ~1; + if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) + result |= -((bfd_vma) 1 << shift); break; } } @@ -132,10 +140,7 @@ wasm_read_leb128 (bfd * abfd, if (length_return != NULL) *length_return = num_read; if (error_return != NULL) - *error_return = ! success; - - if (sign && (shift < 8 * sizeof (result)) && (byte & 0x40)) - result |= -((bfd_vma) 1 << shift); + *error_return = status != 0; return result; } @@ -241,16 +246,10 @@ wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) asymbol *symbols = NULL; sec_ptr space_function_index; - if (! asect) - return FALSE; - - if (strcmp (asect->name, WASM_NAME_SECTION) != 0) - return FALSE; - p = asect->contents; end = asect->contents + asect->size; - if (! p) + if (!p) return FALSE; while (p < end) @@ -267,7 +266,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; @@ -278,10 +277,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; @@ -289,22 +285,24 @@ 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) + symbols = bfd_alloc2 (abfd, tdata->symcount, sizeof (asymbol)); + if (!symbols) return FALSE; for (symcount = 0; p < end && symcount < tdata->symcount; symcount++) @@ -317,14 +315,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]; @@ -345,8 +344,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; } @@ -381,13 +378,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) @@ -396,14 +392,13 @@ 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; @@ -418,9 +413,9 @@ wasm_scan (bfd *abfd) 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); payload_len = wasm_read_leb128 (abfd, &error, &bytes_read, FALSE); if (error) @@ -429,21 +424,18 @@ wasm_scan (bfd *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) - goto error_return; - p = name; - ret = sprintf (p, "%s", prefix); - if (ret < 0 || (bfd_vma) ret != strlen (prefix)) + 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; @@ -454,8 +446,8 @@ wasm_scan (bfd *abfd) if (bfdsec->size != 0) { - bfdsec->contents = bfd_zalloc (abfd, bfdsec->size); - if (! bfdsec->contents) + bfdsec->contents = bfd_alloc (abfd, bfdsec->size); + if (!bfdsec->contents) goto error_return; if (bfd_bread (bfdsec->contents, bfdsec->size, abfd) != bfdsec->size) @@ -473,12 +465,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; } @@ -745,23 +731,30 @@ static const bfd_target * 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;