6l: PE32+ output for Windows amd64 (-H 10), printing via kernel32#8
Open
rafael2knokia wants to merge 1 commit into
Open
6l: PE32+ output for Windows amd64 (-H 10), printing via kernel32#8rafael2knokia wants to merge 1 commit into
rafael2knokia wants to merge 1 commit into
Conversation
Wire the PE writer into 6l so it can produce 64-bit Windows executables
that actually do I/O, the amd64 counterpart to the 386 support on 8l.
src/cmd/ld/pe.{c,h}: add the PE32+ path.
- New IMAGE_OPTIONAL_HEADER64 (ImageBase and the stack/heap sizes widen
to 8 bytes, BaseOfData dropped; written verbatim like the 32-bit
header). peinit() already set pe64 for thechar=='6'; asmbpe() now
emits Magic 0x20b, MajorSubsystem/OS 6.0 (64-bit Windows predates
4.0), LARGE_ADDRESS_AWARE, and fills oh64 from oh.
- The import table now imports GetStdHandle, WriteFile and ExitProcess
from kernel32. peimports() (run from dope(), before reloc()) lays out
the .idata section and defines an __imp_<name> linker symbol at each
import's IAT slot, so a program can call through the thunk with
"MOVQ __imp_WriteFile(SB), AX; CALL AX". IAT entries and the null
terminator are 8 bytes wide under pe64.
- add_import_table() now only writes the bytes (layout done earlier),
and writes them at the section's PointerToRawData rather than the
current EOF (with non-empty .data the file position is not
page-aligned, which left the image "truncated").
- dope() skips zero-size .data/.bss: an empty section does not advance
the virtual-address cursor, so the next section would collide on
VirtualAddress and the loader rejects the image.
src/cmd/6l: compile pe.c (symlink + mkfile), add "-H 10" / goos=windows
handling in obj.c (peinit + case 10, defaulting INITTEXT=PEBASE+0x1000
like 8l), call dope() before reloc() so the __imp_* symbols resolve, and
dispatch asmbpe() from asmb(). 6l has no PE symbol-table path yet, so
obj.c forces -s for -H 10.
tests/s/mini: hello_windows_amd64.s prints "Hello, World!" via
GetStdHandle + WriteFile + ExitProcess (Win64 ABI: args in CX/DX/R8/R9,
32-byte shadow space, 16-byte aligned stack), built with 6l -H 10.
Verified on Linux with wine: `6l -s -H 10` produces a
"PE32+ executable (console) x86-64" (Magic 0x20b, ImageBase 0x400000)
that prints "Hello, World!" and exits 0.
ebb89bd to
d0d0e7c
Compare
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
6l -H 10to emit PE32+ (64-bit) Windows executables that actually do I/O..idataimport table importsGetStdHandle,WriteFileandExitProcessfromkernel32.dll, and the linker defines an__imp_<name>symbol at each import's IAT slot so a program can call through the thunk (MOVQ __imp_WriteFile(SB), AX; CALL AX).tests/s/mini/hello_windows_amd64.sprintsHello, World!and exits 0.Details
IMAGE_OPTIONAL_HEADER64added;asmbpe()emits Magic0x20b, subsystem/OS 6.0,LARGE_ADDRESS_AWARE, fillsoh64fromoh. IAT entries are 8 bytes wide underpe64.peimports()runs fromdope()(moved beforereloc()) to lay out.idataand define the__imp_*symbols so references resolve to the right IAT slots.add_import_table()writes at the section'sPointerToRawData(not EOF), fixing a "file truncated" load error when.datais non-empty.dope()skips zero-size.data/.bssso sections don't collide onVirtualAddress.This PR is now independent of #7 (386 smoke test); both branch from
master.Test plan
6l -s -H 10builds aPE32+ executable (console) x86-64.wine: printsHello, World!, exits 0.8l/5lstill compile the sharedpe.c;mk allintests/s/minipasses.