[lld]lld-link -debug emits zero-characteristic PE sections
- Dominant language
- LLVM
- Stars
- 40.5k
- Forks
- 18.7k
- PR merge metrics
- PR metrics pending
Description
## Summary
With `clang-cl /Zi -fuse-ld=lld`, lld-link emits `_guard_c`, `_guard_d`,
and `memcpy_` with `IMAGE_SECTION_HEADER.Characteristics = 0x00000000`.
Windows then does not use large-page image mapping:
`_PEB.ImageUsesLargePages` is `0y0` with IFEO `UseLargePages=1` enabled.
Verbose-driver output shows that `clang-cl /Zi` invokes `lld-link -debug`.
Without `/Zi`, the same link succeeds (`ImageUsesLargePages = 0y1`).
## Environment
* OS: Windows [fill in version/build]; x64
* lld-link version: LLD 19.1.1
* Compiler driver: MSYS2 MinGW64 `clang-cl` 21.1.8 (`x86_64-pc-windows-msvc`)
* MSVC toolset: 14.43.34808
## Reproduction
Set IFEO `UseLargePages=1` for `stockfish.exe` and grant the test user the
`Lock pages in memory` right. Build with:
```bat
clang-cl /nologo /TC /c /Fomain.obj main.c
clang-cl /nologo /TC /c /Fospecrand.obj specrand.c
clang-cl /nologo /Zi -fuse-ld=lld main.obj specrand.obj ^
/Felld_zi.exe /link /force:multiple /largeaddressaware
```
Rename or copy the executable to `stockfish.exe`, then run:
```bat
cdb -c "dt _PEB @$peb ImageUsesLargePages; q" stockfish.exe
```
## Actual result
```text
_guard_c Characteristics = 0x00000000
_guard_d Characteristics = 0x00000000
memcpy_ Characteristics = 0x00000000
```
`dt _PEB @$peb ImageUsesLargePages` prints `0y0`.
## Expected result
Every output section should have at least one of `IMAGE_SCN_MEM_READ`,
`IMAGE_SCN_MEM_WRITE`, or `IMAGE_SCN_MEM_EXECUTE`. In this case the three
sections can be read-only initialized data (`0x40000040`), allowing
`ImageUsesLargePages = 0y1`.
## Controls
| Linker and flags | `ImageUsesLargePages` |
| --- | --- |
| `clang-cl /Zi -fuse-ld=lld` | `0y0` |
| Same command without `/Zi` | `0y1` |
| MSVC `link.exe /debug` | `0y1` |
## Investigation
The source CRT COMDATs have `Characteristics = 0x00001000`
(`IMAGE_SCN_LNK_COMDAT`) only. `SectionChunk::getOutputCharacteristics()`
in `lld/COFF/Chunks.h` masks characteristics with `permMask | typeMask`;
that mask removes `IMAGE_SCN_LNK_COMDAT`, yielding zero. `Writer.cpp`
normalizes some known section names, but not these ones.
## Possible fix
Assign a sensible default when the masked result is zero, or normalize
these sections as read-only initialized data. A regression test should
assert that emitted PE sections have at least one memory-protection bit.
Contributor guide
Research direction
Start in lld/COFF/Chunks.h at SectionChunk::getOutputCharacteristics(), then compare the section-name normalization in Writer.cpp. Add a regression test covering the /debug or /Zi link case and verify that the affected PE sections have at least one memory-protection bit and that large-page mapping remains enabled.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- compilers, operating-systems, testing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100