Skip to content

Commit

Permalink
Read staticBump from dylink section
Browse files Browse the repository at this point in the history
This allows us to stop depending wasm-emscripten-finalize to
write staticBump which in turn will allow us to stop exporting
`__data_end`.

As a side effect of this the staticBump information is no
longer available in the normal linking mode which means we
can't include dynamic_base in EMSCRIPTEN_METADATA anymore.  One
more nail in the coffin for EMSCRIPTEN_METADATA. See #12231
  • Loading branch information
sbc100 committed Oct 29, 2020
1 parent 538a4f6 commit 228419c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 36 deletions.
35 changes: 15 additions & 20 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from tools import diagnostics
from tools import shared
from tools import gen_struct_info
from tools import webassembly
from tools.shared import WINDOWS, asstr, path_from_root, exit_with_error, asmjs_mangle, treat_as_user_function
from tools.toolchain_profiler import ToolchainProfiler

Expand Down Expand Up @@ -141,8 +142,6 @@ def read_proxied_function_signatures(asmConsts):

shared.Settings.PROXIED_FUNCTION_SIGNATURES = read_proxied_function_signatures(metadata['asmConsts'])

metadata['staticBump'] = align_memory(metadata['staticBump'])

shared.Settings.BINARYEN_FEATURES = metadata['features']
if shared.Settings.RELOCATABLE:
# When building relocatable output (e.g. MAIN_MODULE) the reported table
Expand Down Expand Up @@ -197,20 +196,11 @@ def compile_settings(temp_files):

class Memory():
def __init__(self, metadata):
# Note: if RELOCATABLE, then only relative sizes can be computed, and we don't
# actually write out any absolute memory locations ({{{ STACK_BASE }}}
# does not exist, etc.)

# Memory layout:
# * first the static globals
self.static_bump = metadata['staticBump']
# * then the stack (up on fastcomp, down on upstream)
self.stack_low = align_memory(shared.Settings.GLOBAL_BASE + self.static_bump)
self.stack_high = align_memory(self.stack_low + shared.Settings.TOTAL_STACK)
self.stack_base = self.stack_high
self.stack_max = self.stack_low
# * then dynamic memory begins
self.dynamic_base = align_memory(self.stack_high)
stack_low = align_memory(shared.Settings.GLOBAL_BASE + metadata['staticBump'])
stack_high = align_memory(stack_low + shared.Settings.TOTAL_STACK)
self.stack_base = stack_high
self.stack_max = stack_low
self.dynamic_base = align_memory(stack_high)


def apply_memory(js, memory):
Expand Down Expand Up @@ -319,10 +309,6 @@ def emscript(infile, outfile_js, memfile, temp_files, DEBUG):

update_settings_glue(metadata, DEBUG)

memory = Memory(metadata)
logger.debug('stack_base: %d, stack_max: %d, dynamic_base: %d, static bump: %d', memory.stack_base, memory.stack_max, memory.dynamic_base, memory.static_bump)
shared.Settings.LEGACY_DYNAMIC_BASE = memory.dynamic_base

if not outfile_js:
logger.debug('emscript: skipping js compiler glue')
return
Expand Down Expand Up @@ -358,8 +344,17 @@ def emscript(infile, outfile_js, memfile, temp_files, DEBUG):
pre += '\n' + global_initializers + '\n'

if shared.Settings.RELOCATABLE:
memory = Memory(metadata)
logger.debug('stack_base: %d, stack_max: %d, dynamic_base: %d', memory.stack_base, memory.stack_max, memory.dynamic_base)
memsize = webassembly.parse_dylink_section(infile)[0]
# TODO(sbc): Remove staticBump completely from metadata once this assertion
# has proved its not needed.
assert(memsize == metadata['staticBump'])
metadata['staticBump'] = align_memory(memsize)

pre = apply_memory(pre, memory)
post = apply_memory(post, memory)

pre = apply_static_code_hooks(pre) # In regular runtime, atinits etc. exist in the preamble part
post = apply_static_code_hooks(post) # In MINIMAL_RUNTIME, atinit exists in the postamble part

Expand Down
7 changes: 0 additions & 7 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,6 @@ var EMBIND = 0;
// Whether the main() function reads the argc/argv parameters.
var MAIN_READS_PARAMS = 1;

// Computed during emscripten for the purpose of writing to emscripten_metadata
// section.
// TODO(sbc): Remove this. If emscripten doesn't need it then neither should
// any other loader.
// See https://github.com/emscripten-core/emscripten/issues/12231
var LEGACY_DYNAMIC_BASE = -1;

// List of functions implemented in compiled code; received from the backend.
var IMPLEMENTED_FUNCTIONS = [];

Expand Down
26 changes: 17 additions & 9 deletions tools/webassembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
# change, increment EMSCRIPTEN_ABI_MINOR if EMSCRIPTEN_ABI_MAJOR == 0
# or the ABI change is backwards compatible, otherwise increment
# EMSCRIPTEN_ABI_MAJOR and set EMSCRIPTEN_ABI_MINOR = 0.
EMSCRIPTEN_ABI_MAJOR, EMSCRIPTEN_ABI_MINOR = (0, 28)
EMSCRIPTEN_ABI_MAJOR, EMSCRIPTEN_ABI_MINOR = (0, 29)


def toLEB(x):
Expand Down Expand Up @@ -62,7 +62,6 @@ def add_emscripten_metadata(wasm_file):

mem_size = shared.Settings.INITIAL_MEMORY // WASM_PAGE_SIZE
global_base = shared.Settings.GLOBAL_BASE
dynamic_base = shared.Settings.LEGACY_DYNAMIC_BASE

logger.debug('creating wasm emscripten metadata section with mem size %d' % mem_size)
name = b'\x13emscripten_metadata' # section name, including prefixed size
Expand All @@ -83,7 +82,7 @@ def add_emscripten_metadata(wasm_file):
toLEB(mem_size) +
toLEB(0) +
toLEB(global_base) +
toLEB(dynamic_base) +
toLEB(0) +
# dynamictopPtr, always 0 now
toLEB(0) +

Expand All @@ -109,13 +108,9 @@ def add_emscripten_metadata(wasm_file):
f.write(orig[8:])


def add_dylink_section(wasm_file, needed_dynlibs):
# A wasm shared library has a special "dylink" section, see tools-conventions repo.
# This function adds this section to the beginning on the given file.

def parse_dylink_section(wasm_file):
wasm = open(wasm_file, 'rb').read()
section_name = b'\06dylink' # section name, including prefixed size
file_header = wasm[:8]

# Read the existing section data
offset = 8
Expand All @@ -132,8 +127,17 @@ def add_dylink_section(wasm_file, needed_dynlibs):
table_size, offset = readLEB(section, offset)
table_align, offset = readLEB(section, offset)

return (mem_size, mem_align, table_size, table_align, section_end)


def add_dylink_section(wasm_file, needed_dynlibs):
# A wasm shared library has a special "dylink" section, see tools-conventions repo.
# This function adds this section to the beginning on the given file.

mem_size, mem_align, table_size, table_align, section_end = parse_dylink_section(wasm_file)
logger.debug('creating wasm dynamic library with mem size %d, table size %d, align %d' % (mem_size, table_size, mem_align))

section_name = b'\06dylink' # section name, including prefixed size
contents = (toLEB(mem_size) + toLEB(mem_align) +
toLEB(table_size) + toLEB(0))

Expand Down Expand Up @@ -164,6 +168,10 @@ def add_dylink_section(wasm_file, needed_dynlibs):
contents += toLEB(len(dyn_needed))
contents += dyn_needed

orig = open(wasm_file, 'rb').read()
file_header = orig[:8]
file_remainder = orig[section_end:]

section_size = len(section_name) + len(contents)
with open(wasm_file, 'wb') as f:
# copy magic number and version
Expand All @@ -174,4 +182,4 @@ def add_dylink_section(wasm_file, needed_dynlibs):
f.write(section_name)
f.write(contents)
# copy rest of binary
f.write(wasm[section_end:])
f.write(file_remainder)

0 comments on commit 228419c

Please sign in to comment.