Skip to content

Commit

Permalink
Use llvm-objcpy to strip the producers section, so we strip it by def…
Browse files Browse the repository at this point in the history
…ault even in -O0. Followup to #11996, fixes #12071
  • Loading branch information
kripken committed Aug 28, 2020
1 parent c56a65e commit 4f5f0fc
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 28 deletions.
7 changes: 0 additions & 7 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,6 @@ Current Trunk
`EXPORTED_FUNCTIONS` is not relevant in the deciding the type of application
to build.
- Allow polymorphic types to be used without RTTI when using embind. (#10914)
- Only strip the LLVM producer's section in release builds. In `-O0` builds, we
try to leave the wasm from LLVM unmodified as much as possible, so if it
emitted the producers section, it will be there. Normally that only matters
in release builds, which is not changing here. If you want to not have a
producer's section in debug builds, you can remove it a tool like
`wasm-opt --strip-producers` (which is what Emscripten still does in release
builds, as always) or use `llvm-objcopy`.
- Only strip debug info in release builds + when `-g` is not present. Previously
even in an `-O0` build without `-g` we would strip it. This was not documented
behavior, and has no effect on program behavior, but may be noticeable
Expand Down
25 changes: 17 additions & 8 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,6 @@ def backend_binaryen_passes():
if shared.Settings.OPT_LEVEL > 0:
if shared.Settings.DEBUG_LEVEL < 3:
passes += ['--strip-debug']
if not shared.Settings.EMIT_PRODUCERS_SECTION:
passes += ['--strip-producers']
if shared.Settings.AUTODEBUG:
# adding '--flatten' here may make these even more effective
passes += ['--instrument-locals']
Expand Down Expand Up @@ -2607,12 +2605,23 @@ def do_binaryen(target, asm_target, options, memfile, wasm_binary_target,
options.binaryen_passes += ['--pass-arg=emscripten-sbrk-ptr@%d' % shared.Settings.DYNAMICTOP_PTR]
if shared.Settings.STANDALONE_WASM:
options.binaryen_passes += ['--pass-arg=emscripten-sbrk-val@%d' % shared.Settings.DYNAMIC_BASE]
building.save_intermediate(wasm_binary_target, 'pre-byn.wasm')
args = options.binaryen_passes
building.run_wasm_opt(wasm_binary_target,
wasm_binary_target,
args=args,
debug=intermediate_debug_info)
if options.binaryen_passes:
# if we need to strip the producers section, and we have wasm-opt passes
# to run, do it with them.
if not shared.Settings.EMIT_PRODUCERS_SECTION:
options.binaryen_passes += ['--strip-producers']
building.save_intermediate(wasm_binary_target, 'pre-byn.wasm')
building.run_wasm_opt(wasm_binary_target,
wasm_binary_target,
args=options.binaryen_passes,
debug=intermediate_debug_info)
else:
# we are not running wasm-opt. if we need to strip the producers section
# then do so using llvm-objcpy which is faster and does not rewrite the
# code (which is better for debug info)
if not shared.Settings.EMIT_PRODUCERS_SECTION:
building.save_intermediate(wasm_binary_target, 'pre-noprosec.wasm')
building.strip_producers(wasm_binary_target, wasm_binary_target)

if shared.Settings.BINARYEN_SCRIPTS:
binaryen_scripts = os.path.join(shared.BINARYEN_ROOT, 'scripts')
Expand Down
6 changes: 1 addition & 5 deletions src/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -1147,16 +1147,12 @@ var WASM_ASYNC_COMPILATION = 1;
var WASM_BIGINT = 0;

// WebAssembly defines a "producers section" which compilers and tools can
// annotate themselves in, and LLVM emits this by default. In release builds,
// annotate themselves in, and LLVM emits this by default.
// Emscripten will strip that out so that it is *not* emitted because it
// increases code size, and also some users may not want information
// about their tools to be included in their builds for privacy or security
// reasons, see
// https://github.com/WebAssembly/tool-conventions/issues/93.
// (In debug builds (-O0) we leave the wasm file as it is from LLVM, in which
// case it may contain this section, if you didn't tell LLVM to not emit it. You
// can also run wasm-opt --strip-producers manually, which is what Emscripten
// does in release builds for you automatically.)
var EMIT_PRODUCERS_SECTION = 0;

// If set then generated WASM files will contain a custom
Expand Down
11 changes: 4 additions & 7 deletions tests/test_other.py
Original file line number Diff line number Diff line change
Expand Up @@ -7898,17 +7898,14 @@ def test_separate_dwarf_with_filename_and_path(self):
self.assertIn(b'somewhere.com/hosted.wasm', f.read())

@parameterized({
'O0': (True, ['-O0']), # unoptimized builds try not to modify the LLVM wasm.
'O1': (False, ['-O1']), # optimized builds strip the producer's section
'O2': (False, ['-O2']), # by default.
'O0': (['-O0'],),
'O1': (['-O1'],),
'O2': (['-O2'],),
})
def test_wasm_producers_section(self, expect_producers_by_default, args):
def test_wasm_producers_section(self, args):
self.run_process([EMCC, path_from_root('tests', 'hello_world.c')] + args)
with open('a.out.wasm', 'rb') as f:
data = f.read()
if expect_producers_by_default:
self.assertIn('clang', str(data))
return
# if there is no producers section expected by default, verify that, and
# see that the flag works to add it.
self.assertNotIn('clang', str(data))
Expand Down
10 changes: 9 additions & 1 deletion tools/building.py
Original file line number Diff line number Diff line change
Expand Up @@ -1423,6 +1423,14 @@ def wasm2js(js_file, wasm_file, opt_level, minify_whitespace, use_closure_compil
return js_file


def strip_debug(infile, outfile):
run_process([LLVM_OBJCOPY, '--remove-section=.debug*', infile, outfile])


def strip_producers(infile, outfile):
run_process([LLVM_OBJCOPY, '--remove-section=producers', infile, outfile])


# extract the DWARF info from the main file, and leave the wasm with
# debug into as a file on the side
# TODO: emit only debug sections in the side file, and not the entire
Expand All @@ -1435,7 +1443,7 @@ def emit_debug_on_side(wasm_file, wasm_file_with_dwarf):
embedded_path = shared.Settings.SEPARATE_DWARF_URL or wasm_file_with_dwarf

shutil.move(wasm_file, wasm_file_with_dwarf)
run_process([LLVM_OBJCOPY, '--remove-section=.debug*', wasm_file_with_dwarf, wasm_file])
strip_debug(wasm_file_with_dwarf, wasm_file)

# embed a section in the main wasm to point to the file with external DWARF,
# see https://yurydelendik.github.io/webassembly-dwarf/#external-DWARF
Expand Down

0 comments on commit 4f5f0fc

Please sign in to comment.