示例#1
0
文件: lld.py 项目: aheejin/binaryen
def test_wasm_emscripten_finalize():
  print '\n[ checking wasm-emscripten-finalize testcases... ]\n'

  for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
    print '..', wast_path
    mem_file = wast_path + '.mem'
    extension_arg_map = {
      '.out': [],
      '.mem.out': ['--separate-data-segments', mem_file],
    }
    for ext, ext_args in extension_arg_map.items():
      expected_file = wast_path + ext
      if ext != '.out' and not os.path.exists(expected_file):
        continue

      cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
      cmd += args_for_finalize(os.path.basename(wast_path))
      actual = run_command(cmd)

      if not os.path.exists(expected_file):
        print actual
        fail_with_error('output ' + expected_file + ' does not exist')
      fail_if_not_identical_to_file(actual, expected_file)
      if ext == '.mem.out':
        with open(mem_file) as mf:
          mem = mf.read()
          fail_if_not_identical_to_file(mem, wast_path + '.mem.mem')
        os.remove(mem_file)
示例#2
0
def test_wasm_emscripten_finalize():
    print '\n[ checking wasm-emscripten-finalize testcases... ]\n'

    for wast_path in files_with_pattern(options.binaryen_test, 'lld',
                                        '*.wast'):
        print '..', wast_path
        mem_file = wast_path + '.mem'
        extension_arg_map = {
            '.out': [],
            '.mem.out': ['--separate-data-segments', mem_file],
        }
        for ext, ext_args in extension_arg_map.items():
            expected_file = wast_path + ext
            if ext != '.out' and not os.path.exists(expected_file):
                continue

            cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S'] + ext_args
            cmd += args_for_finalize(os.path.basename(wast_path))
            actual = run_command(cmd)

            if not os.path.exists(expected_file):
                print actual
                fail_with_error('output ' + expected_file + ' does not exist')
            fail_if_not_identical_to_file(actual, expected_file)
            if ext == '.mem.out':
                with open(mem_file) as mf:
                    mem = mf.read()
                    fail_if_not_identical_to_file(mem, wast_path + '.mem.mem')
                os.remove(mem_file)
示例#3
0
def test_wasm_emscripten_finalize():
    print '\n[ checking wasm-emscripten-finalize testcases... ]\n'

    extension_arg_map = {
        '.out': [],
        '.jscall.out': ['--emscripten-reserved-function-pointers=3'],
    }

    for wast_path in files_with_pattern(options.binaryen_test, 'lld',
                                        '*.wast'):
        print '..', wast_path
        for ext, ext_args in extension_arg_map.items():
            expected_file = wast_path + ext
            if ext != '.out' and not os.path.exists(expected_file):
                continue

            cmd = (WASM_EMSCRIPTEN_FINALIZE +
                   [wast_path, '-S', '--global-base=568'] + ext_args)
            actual = run_command(cmd)

            if not os.path.exists(expected_file):
                print actual
                fail_with_error('output ' + expected_file + ' does not exist')
            expected = open(expected_file, 'rb').read()
            if actual != expected:
                fail(actual, expected)
示例#4
0
def test_s2wasm():
    print '\n[ checking .s testcases... ]\n'

    for dot_s_dir in ['dot_s', 'llvm_autogenerated']:
        dot_s_path = os.path.join(options.binaryen_test, dot_s_dir)
        for s in sorted(os.listdir(dot_s_path)):
            if not s.endswith('.s'):
                continue
            print '..', s
            wasm = s.replace('.s', '.wast')
            full = os.path.join(options.binaryen_test, dot_s_dir, s)
            stack_alloc = (['--allocate-stack=1024']
                           if dot_s_dir == 'llvm_autogenerated' else [])
            cmd = S2WASM + [full, '--emscripten-glue'] + stack_alloc
            if s.startswith('start_'):
                cmd.append('--start')
            actual = run_command(cmd)

            # verify output
            expected_file = os.path.join(options.binaryen_test, dot_s_dir,
                                         wasm)
            if not os.path.exists(expected_file):
                print actual
                fail_with_error('output ' + expected_file + ' does not exist')
            expected = open(expected_file, 'rb').read()
            if actual != expected:
                fail(actual, expected)

            # verify with options
            cmd = S2WASM + [full, '--global-base=1024'] + stack_alloc
            run_command(cmd)

            # run wasm-shell on the .wast to verify that it parses
            cmd = WASM_SHELL + [expected_file]
            run_command(cmd)
示例#5
0
def test_s2wasm():
  print '\n[ checking .s testcases... ]\n'

  for dot_s_dir in ['dot_s', 'llvm_autogenerated']:
    dot_s_path = os.path.join(options.binaryen_test, dot_s_dir)
    for s in sorted(os.listdir(dot_s_path)):
      if not s.endswith('.s'):
        continue
      print '..', s
      wasm = s.replace('.s', '.wast')
      full = os.path.join(options.binaryen_test, dot_s_dir, s)
      stack_alloc = (['--allocate-stack=1024']
                     if dot_s_dir == 'llvm_autogenerated'
                     else [])
      cmd = S2WASM + [full, '--emscripten-glue'] + stack_alloc
      if s.startswith('start_'):
        cmd.append('--start')
      actual = run_command(cmd)

      # verify output
      expected_file = os.path.join(options.binaryen_test, dot_s_dir, wasm)
      if not os.path.exists(expected_file):
        print actual
        fail_with_error('output ' + expected_file + ' does not exist')
      expected = open(expected_file, 'rb').read()
      if actual != expected:
        fail(actual, expected)

      # verify with options
      cmd = S2WASM + [full, '--global-base=1024'] + stack_alloc
      run_command(cmd)

      # run wasm-shell on the .wast to verify that it parses
      cmd = WASM_SHELL + [expected_file]
      run_command(cmd)
示例#6
0
        def do_asm2wasm_test():
          actual = run_command(cmd)

          # verify output
          if not os.path.exists(wasm):
            fail_with_error('output .wast file %s does not exist' % wasm)
          fail_if_not_identical_to_file(actual, wasm)

          binary_format_check(wasm, verify_final_result=False)
示例#7
0
def test_linker():
    print '\n[ running linker tests... ]\n'
    # The {main,foo,bar,baz}.s files were created by running clang over the
    # respective c files. The foobar.bar archive was created by running:
    # llvm-ar -format=gnu rc foobar.a quux.s foo.s bar.s baz.s
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
        os.path.join(options.binaryen_test, 'linker', 'archive', 'foobar.a')
    ]
    output = run_command(cmd)
    # foo should come from main.s and return 42
    fail_if_not_contained(output, '(func $foo')
    fail_if_not_contained(output, '(i32.const 42)')
    # bar should be linked in from bar.s
    fail_if_not_contained(output, '(func $bar')
    # quux should be linked in from bar.s even though it comes before bar.s in
    # the archive
    fail_if_not_contained(output, '(func $quux')
    # baz should not be linked in at all
    if 'baz' in output:
        fail_with_error('output should not contain "baz": ' + output)

    # Test an archive using a string table
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
        os.path.join(options.binaryen_test, 'linker', 'archive', 'barlong.a')
    ]
    output = run_command(cmd)
    # bar should be linked from the archive
    fail_if_not_contained(output, '(func $bar')

    # Test exporting memory growth function and emscripten runtime functions
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'),
        '--emscripten-glue', '--allow-memory-growth'
    ]
    output = run_command(cmd)
    expected_funcs = [
        ('__growWasmMemory', '(param $newSize i32)'),
        ('stackSave', '(result i32)'),
        ('stackAlloc', '(param $0 i32) (result i32)'),
        ('stackRestore', '(param $0 i32)'),
    ]
    for name, extra in expected_funcs:
        space = ' ' if extra else ''
        fail_if_not_contained(output,
                              '(export "{0}" (func ${0}))'.format(name))
        for line in output.split('\n'):
            if '(func ${0}'.format(name + space) in line:
                # we found the relevant line for the function definition. remove
                # a (; X ;) comment with its index
                start = line.find('(; ')
                if start >= 0:
                    end = line.find(' ;)')
                    line = line[:start] + line[end + 4:]
                fail_if_not_contained(
                    line, '(func ${0}'.format(name + space + extra))
示例#8
0
        def do_asm2wasm_test():
          actual = run_command(cmd)

          # verify output
          if not os.path.exists(wasm):
            fail_with_error('output .wast file %s does not exist' % wasm)
          fail_if_not_identical_to_file(actual, wasm)

          binary_format_check(wasm, verify_final_result=False)
示例#9
0
def test_s2wasm():
    print '\n[ checking .s testcases... ]\n'

    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'dot_s', 'basics.s'),
        '--import-memory'
    ]
    output = run_command(cmd)
    fail_if_not_contained(output, '(import "env" "memory" (memory $0 1))')

    extension_arg_map = {
        '.wast': [],
        '.clamp.wast': ['--trap-mode=clamp'],
        '.js.wast': ['--trap-mode=js'],
        '.jscall.wast': ['--emscripten-reserved-function-pointers=3'],
    }
    for dot_s_dir in ['dot_s', 'llvm_autogenerated']:
        dot_s_path = os.path.join(options.binaryen_test, dot_s_dir)
        for s in sorted(os.listdir(dot_s_path)):
            if not s.endswith('.s'):
                continue
            print '..', s
            for ext, ext_args in extension_arg_map.iteritems():
                wasm = s.replace('.s', ext)
                expected_file = os.path.join(options.binaryen_test, dot_s_dir,
                                             wasm)
                expected_exists = os.path.exists(expected_file)
                if ext != '.wast' and not expected_exists:
                    continue

                full = os.path.join(options.binaryen_test, dot_s_dir, s)
                stack_alloc = (['--allocate-stack=1024']
                               if dot_s_dir == 'llvm_autogenerated' else [])
                cmd = S2WASM + [full, '--emscripten-glue'
                                ] + stack_alloc + ext_args
                if s.startswith('start_'):
                    cmd.append('--start')
                actual = run_command(cmd)

                # verify output
                if not expected_exists:
                    print actual
                    fail_with_error('output ' + expected_file +
                                    ' does not exist')
                expected = open(expected_file, 'rb').read()
                if actual != expected:
                    fail(actual, expected)

                # verify with options
                cmd = S2WASM + [full, '--global-base=1024'] + stack_alloc
                run_command(cmd)

                # run wasm-shell on the .wast to verify that it parses
                cmd = WASM_SHELL + [expected_file]
                run_command(cmd)
示例#10
0
                def do_asm2wasm_test():
                    actual = run_command(cmd)

                    # verify output
                    if not os.path.exists(wasm):
                        fail_with_error('output .wast file %s does not exist' %
                                        wasm)
                    expected = open(wasm, 'rb').read()
                    if actual != expected:
                        fail(actual, expected)

                    binary_format_check(wasm, verify_final_result=False)
示例#11
0
def test_wasm_emscripten_finalize():
  print '\n[ checking wasm-emscripten-finalize testcases... ]\n'

  for wast_path in files_with_pattern(options.binaryen_test, 'lld', '*.wast'):
    print '..', wast_path
    expected_file = wast_path + '.out'
    cmd = WASM_EMSCRIPTEN_FINALIZE + [wast_path, '-S']
    actual = run_command(cmd)

    if not os.path.exists(expected_file):
      print actual
      fail_with_error('output ' + expected_file + ' does not exist')
    expected = open(expected_file, 'rb').read()
    if actual != expected:
      fail(actual, expected)
示例#12
0
def test_wasm_link_metadata():
  print '\n[ checking wasm-link-metadata testcases... ]\n'

  for obj_path in files_with_pattern(options.binaryen_test, 'lld', '*.o'):
    print '..', obj_path
    expected_file = obj_path.replace('.o', '.json')

    cmd = WASM_LINK_METADATA + [obj_path]
    actual = run_command(cmd)

    if not os.path.exists(expected_file):
      print actual
      fail_with_error('output ' + expected_file + ' does not exist')
    expected = open(expected_file, 'rb').read()
    if actual != expected:
      fail(actual, expected)
示例#13
0
def test_linker():
    print '\n[ running linker tests... ]\n'
    # The {main,foo,bar,baz}.s files were created by running clang over the
    # respective c files. The foobar.bar archive was created by running:
    # llvm-ar -format=gnu rc foobar.a quux.s foo.s bar.s baz.s
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
        os.path.join(options.binaryen_test, 'linker', 'archive', 'foobar.a')
    ]
    output = run_command(cmd)
    # foo should come from main.s and return 42
    fail_if_not_contained(output, '(func $foo')
    fail_if_not_contained(output, '(i32.const 42)')
    # bar should be linked in from bar.s
    fail_if_not_contained(output, '(func $bar')
    # quux should be linked in from bar.s even though it comes before bar.s in
    # the archive
    fail_if_not_contained(output, '(func $quux')
    # baz should not be linked in at all
    if 'baz' in output:
        fail_with_error('output should not contain "baz": ' + output)

    # Test an archive using a string table
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
        os.path.join(options.binaryen_test, 'linker', 'archive', 'barlong.a')
    ]
    output = run_command(cmd)
    # bar should be linked from the archive
    fail_if_not_contained(output, '(func $bar')

    # Test exporting memory growth function
    cmd = S2WASM + [
        os.path.join(options.binaryen_test, 'linker', 'main.s'),
        '--emscripten-glue', '--allow-memory-growth'
    ]
    output = run_command(cmd)
    fail_if_not_contained(
        output, '(export "__growWasmMemory" (func $__growWasmMemory))')
    fail_if_not_contained(output,
                          '(func $__growWasmMemory (param $newSize i32)')
示例#14
0
def test_linker():
  print '\n[ running linker tests... ]\n'
  # The {main,foo,bar,baz}.s files were created by running clang over the
  # respective c files. The foobar.bar archive was created by running:
  # llvm-ar -format=gnu rc foobar.a quux.s foo.s bar.s baz.s
  cmd = S2WASM + [
      os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
      os.path.join(options.binaryen_test, 'linker', 'archive', 'foobar.a')]
  output = run_command(cmd)
  # foo should come from main.s and return 42
  fail_if_not_contained(output, '(func $foo')
  fail_if_not_contained(output, '(i32.const 42)')
  # bar should be linked in from bar.s
  fail_if_not_contained(output, '(func $bar')
  # quux should be linked in from bar.s even though it comes before bar.s in
  # the archive
  fail_if_not_contained(output, '(func $quux')
  # baz should not be linked in at all
  if 'baz' in output:
    fail_with_error('output should not contain "baz": ' + output)

  # Test an archive using a string table
  cmd = S2WASM + [
      os.path.join(options.binaryen_test, 'linker', 'main.s'), '-l',
      os.path.join(options.binaryen_test, 'linker', 'archive', 'barlong.a')]
  output = run_command(cmd)
  # bar should be linked from the archive
  fail_if_not_contained(output, '(func $bar')

  # Test exporting memory growth function
  cmd = S2WASM + [
      os.path.join(options.binaryen_test, 'linker', 'main.s'),
      '--emscripten-glue', '--allow-memory-growth']
  output = run_command(cmd)
  fail_if_not_contained(
      output, '(export "__growWasmMemory" (func $__growWasmMemory))')
  fail_if_not_contained(output, '(func $__growWasmMemory (param $newSize i32)')
示例#15
0
def test_asm2wasm():
  print '[ checking asm2wasm testcases... ]\n'

  for asm in tests:
    if not asm.endswith('.asm.js'):
      continue
    for precise in [0, 1, 2]:
      for opts in [1, 0]:
        cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)]
        if 'threads' in asm:
          cmd += ['--enable-threads']
        wasm = asm.replace('.asm.js', '.fromasm')
        if not precise:
          cmd += ['--trap-mode=allow', '--ignore-implicit-traps']
          wasm += '.imprecise'
        elif precise == 2:
          cmd += ['--trap-mode=clamp']
          wasm += '.clamp'
        if not opts:
          wasm += '.no-opts'
          if precise:
            cmd += ['-O0']  # test that -O0 does nothing
        else:
          cmd += ['-O']
        if 'debugInfo' in asm:
          cmd += ['-g']
        if 'noffi' in asm:
          cmd += ['--no-legalize-javascript-ffi']
        if precise and opts:
          # test mem init importing
          open('a.mem', 'wb').write(asm)
          cmd += ['--mem-init=a.mem']
          if asm[0] == 'e':
            cmd += ['--mem-base=1024']
        if '4GB' in asm:
          cmd += ['--mem-max=4294967296']
        if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm:
          cmd += ['--wasm-only']
        wasm = os.path.join(options.binaryen_test, wasm)
        print '..', asm, wasm

        def do_asm2wasm_test():
          actual = run_command(cmd)

          # verify output
          if not os.path.exists(wasm):
            fail_with_error('output .wast file %s does not exist' % wasm)
          fail_if_not_identical_to_file(actual, wasm)

          binary_format_check(wasm, verify_final_result=False)

        # test both normally and with pass debug (so each inter-pass state
        # is validated)
        old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
        try:
          os.environ['BINARYEN_PASS_DEBUG'] = '1'
          print "With BINARYEN_PASS_DEBUG=1:"
          do_asm2wasm_test()
          del os.environ['BINARYEN_PASS_DEBUG']
          print "With BINARYEN_PASS_DEBUG disabled:"
          do_asm2wasm_test()
        finally:
          if old_pass_debug is not None:
            os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
          else:
            if 'BINARYEN_PASS_DEBUG' in os.environ:
              del os.environ['BINARYEN_PASS_DEBUG']

        # verify in wasm
        if options.interpreter:
          # remove imports, spec interpreter doesn't know what to do with them
          subprocess.check_call(WASM_OPT + ['--remove-imports', wasm],
                                stdout=open('ztemp.wast', 'w'),
                                stderr=subprocess.PIPE)
          proc = subprocess.Popen([options.interpreter, 'ztemp.wast'],
                                  stderr=subprocess.PIPE)
          out, err = proc.communicate()
          if proc.returncode != 0:
            try:  # to parse the error
              reported = err.split(':')[1]
              start, end = reported.split('-')
              start_line, start_col = map(int, start.split('.'))
              lines = open('ztemp.wast').read().split('\n')
              print
              print '=' * 80
              print lines[start_line - 1]
              print (' ' * (start_col - 1)) + '^'
              print (' ' * (start_col - 2)) + '/_\\'
              print '=' * 80
              print err
            except Exception:
              # failed to pretty-print
              fail_with_error('wasm interpreter error: ' + err)
            fail_with_error('wasm interpreter error')

        # verify debug info
        if 'debugInfo' in asm:
          jsmap = 'a.wasm.map'
          cmd += ['--source-map', jsmap,
                  '--source-map-url', 'http://example.org/' + jsmap,
                  '-o', 'a.wasm']
          run_command(cmd)
          if not os.path.isfile(jsmap):
            fail_with_error('Debug info map not created: %s' % jsmap)
          with open(jsmap, 'rb') as actual:
            fail_if_not_identical_to_file(actual.read(), wasm + '.map')
          with open('a.wasm', 'rb') as binary:
            url_section_name = bytearray([16]) + bytearray('sourceMappingURL')
            url = 'http://example.org/' + jsmap
            assert len(url) < 256, 'name too long'
            url_section_contents = bytearray([len(url)]) + bytearray(url)
            print url_section_name
            binary_contents = bytearray(binary.read())
            if url_section_name not in binary_contents:
              fail_with_error('source map url section not found in binary')
            url_section_index = binary_contents.index(url_section_name)
            if url_section_contents not in binary_contents[url_section_index:]:
              fail_with_error('source map url not found in url section')
示例#16
0
def test_asm2wasm():
  print '[ checking asm2wasm testcases... ]\n'

  for asm in tests:
    if not asm.endswith('.asm.js'):
      continue
    for precise in [0, 1, 2]:
      for opts in [1, 0]:
        cmd = ASM2WASM + [os.path.join(options.binaryen_test, asm)]
        if 'threads' in asm:
          cmd += ['--enable-threads']
        wasm = asm.replace('.asm.js', '.fromasm')
        if not precise:
          cmd += ['--trap-mode=allow', '--ignore-implicit-traps']
          wasm += '.imprecise'
        elif precise == 2:
          cmd += ['--trap-mode=clamp']
          wasm += '.clamp'
        if not opts:
          wasm += '.no-opts'
          if precise:
            cmd += ['-O0']  # test that -O0 does nothing
        else:
          cmd += ['-O']
        if 'debugInfo' in asm:
          cmd += ['-g']
        if 'noffi' in asm:
          cmd += ['--no-legalize-javascript-ffi']
        if precise and opts:
          # test mem init importing
          open('a.mem', 'wb').write(asm)
          cmd += ['--mem-init=a.mem']
          if asm[0] == 'e':
            cmd += ['--mem-base=1024']
        if 'i64' in asm or 'wasm-only' in asm or 'noffi' in asm:
          cmd += ['--wasm-only']
        wasm = os.path.join(options.binaryen_test, wasm)
        print '..', asm, wasm

        def do_asm2wasm_test():
          actual = run_command(cmd)

          # verify output
          if not os.path.exists(wasm):
            fail_with_error('output .wast file %s does not exist' % wasm)
          fail_if_not_identical_to_file(actual, wasm)

          binary_format_check(wasm, verify_final_result=False)

        # test both normally and with pass debug (so each inter-pass state
        # is validated)
        old_pass_debug = os.environ.get('BINARYEN_PASS_DEBUG')
        try:
          os.environ['BINARYEN_PASS_DEBUG'] = '1'
          print "With BINARYEN_PASS_DEBUG=1:"
          do_asm2wasm_test()
          del os.environ['BINARYEN_PASS_DEBUG']
          print "With BINARYEN_PASS_DEBUG disabled:"
          do_asm2wasm_test()
        finally:
          if old_pass_debug is not None:
            os.environ['BINARYEN_PASS_DEBUG'] = old_pass_debug
          else:
            if 'BINARYEN_PASS_DEBUG' in os.environ:
              del os.environ['BINARYEN_PASS_DEBUG']

        # verify in wasm
        if options.interpreter:
          # remove imports, spec interpreter doesn't know what to do with them
          subprocess.check_call(WASM_OPT + ['--remove-imports', wasm],
                                stdout=open('ztemp.wast', 'w'),
                                stderr=subprocess.PIPE)
          proc = subprocess.Popen([options.interpreter, 'ztemp.wast'],
                                  stderr=subprocess.PIPE)
          out, err = proc.communicate()
          if proc.returncode != 0:
            try:  # to parse the error
              reported = err.split(':')[1]
              start, end = reported.split('-')
              start_line, start_col = map(int, start.split('.'))
              lines = open('ztemp.wast').read().split('\n')
              print
              print '=' * 80
              print lines[start_line - 1]
              print (' ' * (start_col - 1)) + '^'
              print (' ' * (start_col - 2)) + '/_\\'
              print '=' * 80
              print err
            except Exception:
              # failed to pretty-print
              fail_with_error('wasm interpreter error: ' + err)
            fail_with_error('wasm interpreter error')

        # verify debug info
        if 'debugInfo' in asm:
          jsmap = 'a.wasm.map'
          cmd += ['--source-map', jsmap,
                  '--source-map-url', 'http://example.org/' + jsmap,
                  '-o', 'a.wasm']
          run_command(cmd)
          if not os.path.isfile(jsmap):
            fail_with_error('Debug info map not created: %s' % jsmap)
          with open(jsmap, 'rb') as actual:
            fail_if_not_identical_to_file(actual.read(), wasm + '.map')
          with open('a.wasm', 'rb') as binary:
            url_section_name = bytearray([16]) + bytearray('sourceMappingURL')
            url = 'http://example.org/' + jsmap
            assert len(url) < 256, 'name too long'
            url_section_contents = bytearray([len(url)]) + bytearray(url)
            print url_section_name
            binary_contents = bytearray(binary.read())
            if url_section_name not in binary_contents:
              fail_with_error('source map url section not found in binary')
            url_section_index = binary_contents.index(url_section_name)
            if url_section_contents not in binary_contents[url_section_index:]:
              fail_with_error('source map url not found in url section')