michaeleisel/zld

zld fails with the can't write to output file: <output-file>, errno=22

Closed this issue · 6 comments

This happens for some specific targets only. Observing it in Xcode 12.5 with zld 1.3.2. It is obvious that the error is happening on OutputFile.cpp#L3964. But not sure why we are getting EINVAL. The documentation https://linux.die.net/man/2/write suggests:

EINVAL
fd is attached to an object which is unsuitable for writing; or the file was opened with the O_DIRECT flag, and either the > address specified in buf, the value specified in count, or the current file offset is not suitably aligned.

odd. yeah 1.3.2 moved to using write instead of the mmap approach because the latter was producing an executable that, for some reason, failed signing checks. copying that identical file somewhere else on the file system, though, would make the checks start working again. so, this may be more of that same weirdness. do you have a reproducible case you can send me?

Wow, thanks for the quick response.

Unfortunately, this is happening inside our complicated Bazel setup and it'll be super difficult to figure out an open-source reproducer that I could send you. If you have some tips on what could be causing it, I could try debugging it here and get back to you.

one thing i'd be curious about is if bazel is involved, e.g. if the linker is trying to overwrite a binary that bazel has write-protected. i wonder if a small bazel project has this issue

You are right, zld succeeds if I revert 65ac7c2

if the linker is trying to overwrite a binary that bazel has write-protected.

I can reproduce this even if I build through Xcode and generate output to /tmp/blah. One thing I am observing is that this happens only for binaries that are huge in size, Binaries of size ~ 2.1 G. Could there be some limitations to the write function?

looking at man 2 write, i think i see the cause:

[EINVAL]           The sum of the iov_len values in the iov array overflows a 32-bit integer.

fixed in c300c57