From 6d86e75f829ea02c100e6e3fd0013bff5b589d12 Mon Sep 17 00:00:00 2001 From: titzer Date: Thu, 8 Oct 2015 13:50:20 -0700 Subject: Update rationale for indirect calls --- Rationale.md | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) (limited to 'Rationale.md') diff --git a/Rationale.md b/Rationale.md index 2065ff6..e689fce 100644 --- a/Rationale.md +++ b/Rationale.md @@ -156,22 +156,29 @@ TODO ## Indirect Calls -The exact semantics of indirect function calls, function pointers, and what -happens when calling the wrong function, are still being discussed. - -Fundamentally linear memory is a simple collection of bytes, which means that -some integral representation of function pointers must exist. It's desirable to -hide the actual address of generated code from untrusted code because that would -be an unfortunate information leak which could have negative security -implications. Indirection is therefore desired. - -One extra concern is that existing C++ code sometimes stores data inside of what -is usually a function pointer. This is expected to keep working. - -Dynamic linking further complicates this: WebAssembly cannot simply standardize -on fixed-size function tables since dynamically linked code can add new -functions, as well as remove them. - +The table-based scheme for indirect function calls was motivated by the need +to represent function pointers as integer values that can be stored into the +linear memory, as well as to enforce basic safety properties such as a +calling a function with the wrong signature does not destroy the safety +guarantees of WebAssembly. + +Languages like C and C++ that compile to WebAssembly also imposed +requirements, such as the uniqueness of function pointers and the ability +to compare function pointers to data pointers, or treat data as function +pointers. + +Several alternatives to direct indices with a heterogeneous indirect function table +were considered, from alternatives with multiple tables to statically typed function +pointers that can be mapped back and forth to integers. With the added complication +of dynamic linking, none of these alternatives perfectly fit the requirements. + +The current design requires two dynamic checks when invoking a function pointer: +a bounds check against the size of the indirect function table and a signature check +for the function at that index against an expected signature. Some dynamic optimization +techniques (e.g. inline caches, or a one-element cache), can reduce the number of +checks in common cases. Other techniques such as trading a bounds check for a mask or +segregating the table per signature to require only a bounds check could be considered +in the future. ## Expressions with Control Flow -- cgit v1.2.3 From ab54ccefbb771fb09352cd644cc0ac6d6d5f40a2 Mon Sep 17 00:00:00 2001 From: titzer Date: Thu, 8 Oct 2015 15:11:01 -0700 Subject: Update Rationale.md --- Rationale.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'Rationale.md') diff --git a/Rationale.md b/Rationale.md index e689fce..652c4de 100644 --- a/Rationale.md +++ b/Rationale.md @@ -160,7 +160,9 @@ The table-based scheme for indirect function calls was motivated by the need to represent function pointers as integer values that can be stored into the linear memory, as well as to enforce basic safety properties such as a calling a function with the wrong signature does not destroy the safety -guarantees of WebAssembly. +guarantees of WebAssembly. In particular, an exact signature match implies +an internal machine-level ABI match, which some engines require to ensure safety. +An indirection also avoids a possible information leak through raw code addresses. Languages like C and C++ that compile to WebAssembly also imposed requirements, such as the uniqueness of function pointers and the ability @@ -170,7 +172,8 @@ pointers. Several alternatives to direct indices with a heterogeneous indirect function table were considered, from alternatives with multiple tables to statically typed function pointers that can be mapped back and forth to integers. With the added complication -of dynamic linking, none of these alternatives perfectly fit the requirements. +of dynamic linking and dynamic code generation, none of these alternatives perfectly +fit the requirements. The current design requires two dynamic checks when invoking a function pointer: a bounds check against the size of the indirect function table and a signature check @@ -178,7 +181,8 @@ for the function at that index against an expected signature. Some dynamic optim techniques (e.g. inline caches, or a one-element cache), can reduce the number of checks in common cases. Other techniques such as trading a bounds check for a mask or segregating the table per signature to require only a bounds check could be considered -in the future. +in the future. Also, if tables are small enough, an engine can internally use per-signature +tables filled with failure handlers to avoid one check. ## Expressions with Control Flow -- cgit v1.2.3 From 1fe7ecbd65c90b74a0f158037b8e1c7dd351df9a Mon Sep 17 00:00:00 2001 From: titzer Date: Fri, 23 Oct 2015 12:03:12 -0700 Subject: Update Rationale.md --- Rationale.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Rationale.md') diff --git a/Rationale.md b/Rationale.md index 652c4de..7757b74 100644 --- a/Rationale.md +++ b/Rationale.md @@ -158,7 +158,7 @@ TODO The table-based scheme for indirect function calls was motivated by the need to represent function pointers as integer values that can be stored into the -linear memory, as well as to enforce basic safety properties such as a +linear memory, as well as to enforce basic safety properties such as calling a function with the wrong signature does not destroy the safety guarantees of WebAssembly. In particular, an exact signature match implies an internal machine-level ABI match, which some engines require to ensure safety. -- cgit v1.2.3