-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Fix signedness/type mismatches when marshaling stat-related structs #24772
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
Fix signedness/type mismatches when marshaling stat-related structs #24772
Conversation
lgtm, but I'm fine with #24769 landing first too. |
src/lib/libsyscall.js
Outdated
@@ -60,20 +60,20 @@ var SyscallsLibrary = { | |||
{{{ makeSetValue('buf', C_STRUCTS.stat.st_mtim.tv_nsec, '(mtime % 1000) * 1000 * 1000', SIZE_TYPE) }}}; | |||
{{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_sec, 'Math.floor(ctime / 1000)', 'i64') }}}; | |||
{{{ makeSetValue('buf', C_STRUCTS.stat.st_ctim.tv_nsec, '(ctime % 1000) * 1000 * 1000', SIZE_TYPE) }}}; | |||
{{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'i64') }}}; | |||
{{{ makeSetValue('buf', C_STRUCTS.stat.st_ino, 'stat.ino', 'u64') }}}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC the signed-ness of the type only really matter for makeGetValue
.. is that right? i.e. its when reading the bits that its important to interpret them.
Supporting evidence for this is that the makeSetValue
code doesn't even have code paths for handling u64
and u53
here:
Lines 453 to 466 in 90250aa
if (type == 'i64' && !WASM_BIGINT) { | |
// If we lack BigInt support we must fall back to an reading a pair of I32 | |
// values. | |
// prettier-ignore | |
return '(tempI64 = [' + splitI64(value) + '], ' + | |
makeSetValueImpl(ptr, pos, 'tempI64[0]', 'i32') + ',' + | |
makeSetValueImpl(ptr, getFastValue(pos, '+', getNativeTypeSize('i32')), 'tempI64[1]', 'i32') + ')'; | |
} | |
const offset = calcFastOffset(ptr, pos); | |
if (type === 'i53') { | |
return `writeI53ToI64(${offset}, ${value})`; | |
} |
I think maybe just always use the signed array views works for setting values?
I'm not sure what happens if we write a negative number to an unsigned typed array, but I guess its undefined behaviour from our POV and we should assert in debug build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the failing tests, there's seems to be indeed support missing for -sWASM_BIGINT=0
and makeSetValue(x, y, z, 'u64')
. Commit 5511235 reverts that part.
I'm not sure if this signedness mismatch only affects makeGetValue()
, since getHeapForType()
is also used in makeSetValue()
(e.g. HEAP32
versus HEAPU32
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this signedness mismatch only affects
makeGetValue()
, sincegetHeapForType()
is also used inmakeSetValue()
(e.g.HEAP32
versusHEAPU32
).
I'm not sure either, but I would say that seems like signedness is critical when reading values (since the bytes need to be interpreted), but maybe not critical when writing them.
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (1) test expectation files were updated by running the tests with `--rebaseline`: ``` code_size/test_codesize_hello_dylink.json: 45583 => 45582 [-1 bytes / -0.00%] Average change: -0.00% (-0.00% - -0.00%) ```
This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (3) test expectation files were updated by running the tests with `--rebaseline`: ``` code_size/test_codesize_cxx_wasmfs.json: 176935 => 176938 [+3 bytes / +0.00%] code_size/test_codesize_files_wasmfs.json: 55778 => 55781 [+3 bytes / +0.01%] code_size/test_codesize_hello_dylink_all.json: 844699 => 844697 [-2 bytes / -0.00%] Average change: +0.00% (-0.00% - +0.01%) ```
The codesize tests appear to be quite sensitive, especially |
Yes, I apologize for that. I'm not sure if we should remove that test again.. maybe? Or we should have it auto-update as part of the review process. |
I'm not certain what the ideal solution is, but one possibility is to create a bot that automatically updates test expectations whenever a specific label (perhaps reuse code size or introduce "needs-rebaseline"?) is applied to a PR. Once the bot completes the update, it would remove the label. Using labels helps prevent potential abuse, since applying them requires triage access or higher (this idea is also somewhat inspired by LLVM's convenient |
... ah, I forgot that this only works when the "Allow edits by maintainers" option is enabled, though I believe it's enabled by default. |
Yes, we already have an action that will create rebasline CLs for main: https://github.com/emscripten-core/emscripten/actions/workflows/rebaseline-tests.yml Figuring out how to make this work PRs in flight is what I'd like to do. I've not get written a bot that responds to labels of commands but it seems possible. |
No description provided.