Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wasm-linker: feature compatibility validation #13287

Merged
merged 6 commits into from Oct 26, 2022

Conversation

Luukdegram
Copy link
Sponsor Member

Wasm object files and binaries can contain an optional section called the target_features section. This section describes features that are used, required, or disallowed. This PR implements the validation of each linked object file and its features to ensure the generated binary is compatible. For example, when object A uses the feature 'atomics' but object B disallows the feature 'atomics' it's a linker error. Only when the user has specified features or any of the linked object files do, will we emit this section. As it's optional, it's omitted when providing the -fstrip flag. When the user did not specify any features, we instead infer them from any of the linked object files. For the curious reader, more information can be found at: https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md#target-features-section

src/link/Wasm.zig Outdated Show resolved Hide resolved
Verifies disallowed and used/required features. After verifying,
all errors will be emit to notify the user about incompatible
features. When the user did not define any featureset, we infer
the features from the linked objects instead.
When the result is not being stripped, we emit the `target_features`
section based on all the used features. This includes features
inferred from linked object files.
Considering we know all possible features upfront, we can use an
array and therefore do not have to dynamically allocate memory.
Using this trick we can also easily order all features based
the same ordering as found in `std.Target.wasm` which is the same
ordering used by LLVM and the like.
When an object file or binary contains the target_features section
we can now parse and then dump its contents in string format so
we can use them in our linker tests to verify the features section.
Adds a test for inferring features based on a different object file.
Also provides a test case where cpu features are explicitly set on
a library where the end result will output said target features.
The list of features a Wasm object/binary file can emit can differ
from the list of cpu features. The reason for this is because the
"target_features" section also contains linker features. An example
of this is the "shared-mem" feature, which is a feature for the linker
and not that of the cpu target as defined by LLVM.
Considering all possible features are known by the linker during
compile-time, we can create arrays on the stack instead of
dynamically allocating hash maps. We use a simple bitset to determine
whether a feature is enabled or not, and from which object file
it originates. This allows us to make feature validation slightly
faster and use less runtime memory.
In the future this could be enhanced further by having a single
array instead with a more sophisticated bitset.
Copy link
Member

@kubkon kubkon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! I know that it might look like the mechanism for extracting the features is really terse and messy, but it could easily be pulled into a couple of inlined helper function calls down the line and it would make potential contributors none the wiser. Awesome work!

@Luukdegram Luukdegram merged commit 875e98a into ziglang:master Oct 26, 2022
@Luukdegram Luukdegram deleted the wasm-features branch October 26, 2022 12:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants