post-process-pe: show section names in warnings/errors and strip COFF symbol tables - #815
Open
vathpela wants to merge 4 commits into
Open
post-process-pe: show section names in warnings/errors and strip COFF symbol tables#815vathpela wants to merge 4 commits into
vathpela wants to merge 4 commits into
Conversation
vathpela
force-pushed
the
strip-coff-symtabs
branch
9 times, most recently
from
July 22, 2026 17:24
53e16e4 to
3769604
Compare
vathpela
marked this pull request as ready for review
July 22, 2026 17:46
vathpela
force-pushed
the
strip-coff-symtabs
branch
2 times, most recently
from
July 23, 2026 17:40
fc920b9 to
79d7974
Compare
Currently we have this in our mkosi configs: [Config] MinimumVersion=commit:dec7c3e754810ae6d2382d0b5e4762d7250b0254 The theory is this ensures we have a new enough mkosi for all the features / configs we're using to actually work. In practice this is always true, so what this config option does is break things when I try to duplicate results on a distro-packaged mkosi (i.e. not a git checkout done by the github systemd/mkosi@main action), with this not at all cryptic error message: $ mkosi sandbox -- mkosi --distribution fedora --kernel-command-line-extra=systemd.unit=mkosi-test.service qemu ‣ Cannot check mkosi git version, not running mkosi from a git repository So this patch comments it out. I'd remove it entirely, but it's useful to see which version things were intended for. Signed-off-by: Peter Jones <pjones@redhat.com>
Previously post-process-pe would complain like:
validate_nx_compat():467: Section 9 has Virtual Address 0x00227000 that isn't section aligned (0x00010000)
which is moderately useful, but stealthily tricks the user into trying
to figure out if we're counting from 0 or 1, which then makes them have
to resolve this by looking at the actual addresses we're complaining
about to match it up.
This patch changes that output to:
validate_nx_compat():467: Section 9 (".rodata") has Virtual Address 0x00227000 that isn't section aligned (0x00010000)
Signed-off-by: Peter Jones <pjones@redhat.com>
While investigating how to make post-process-pe show section names, I
discovered yet another way our objcopy magic binaries are amazing.
If you dump, say, our shimx64.efi binary with objdump, you'll see
something like:
$ objdump -h shimx64.efi
shimx64.efi: file format pei-x86-64
Sections:
Idx Name Size VMA LMA File off Algn
0 .eh_frame 00038f6c 000000000000a000 000000000000a000 00001000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 000e4d52 0000000000043000 0000000000043000 0003a000 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .data.ident 00000066 0000000000129000 0000000000129000 0011f000 2**4
CONTENTS, ALLOC, LOAD, DATA
3 .sbatlevel 0000004f 000000000012a000 000000000012a000 00120000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .data 0005d128 000000000012b000 000000000012b000 00121000 2**4
CONTENTS, ALLOC, LOAD, DATA
5 .reloc 0000000c 0000000000189000 0000000000189000 0017f000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .vendor_cert 000008fa 000000000018a000 000000000018a000 00180000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .dynamic 00000130 000000000018b000 000000000018b000 00181000 2**2
CONTENTS, ALLOC, LOAD, DATA
8 .rela 00034de8 000000000018c000 000000000018c000 00182000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .sbat 00000083 00000000001c1000 00000000001c1000 001b7000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .dynsym 0001cd70 00000000001c2000 00000000001c2000 001b8000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .dynstr 0001a063 00000000001df000 00000000001df000 001d5000 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
There's no .strtab or .symtab (and objdump would hide them from you
anyway...), because we post-processed this from a shared object, so
everything is in .dynsym and .dynstr. So you figure the section names
are in there, right? And this binary is approximately 2027619 bytes
long, plus maybe a few KiB for signatures at the end. Right?
But then you look harder at ".eh_frame", the first section name longer
than 8 characters, has this in the raw section header:
00000188 2f 34 00 00 00 00 00 00 |/4......|
00000190 6c 8f 03 00 00 a0 00 00 00 90 03 00 00 10 00 00 |l...............|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 40 00 00 40 |............@..@|
In PE, the /4 means it's at position 4 in the strings. But it's not:
String section [15] '.dynstr' contains 106595 bytes at offset 0x1df000:
[ 0]
[ 1] ImageBase
[ b] _relocate
[ 15] __stack_chk_guard
[ 27] SHIM_LOCK_GUID
[ 36] get_variable
[ 43] console_print
[ 51] __stack_chk_fail
Because it's in another string table that's completely hidden! Which
objdump knows how to look up but doesn't tell you about because it's not
in a section for no good reason.
If you dump the COFF file header, you'll see:
0x8C 0x8 PointerToSymbolTable: 0x1F0000
0x90 0xC NumberOfSymbols: 0x3B1B
And sure enough if you hex dump at 0x1f0000 you'll see a COFF symbol
table that absolutely nothing is using, and if you dump
0x1f0000 + 0x3b1b * 18, you'll see:
002327e6 ff 4f 02 00 2e 65 68 5f 66 72 |..O...eh_fr|
002327f0 61 6d 65 00 2e 64 61 74 61 2e 69 64 65 6e 74 00 |ame..data.ident.|
00232800 2e 73 62 61 74 6c 65 76 65 6c 00 2e 76 65 6e 64 |.sbatlevel..vend|
00232810 6f 72 5f 63 65 72 74 00 64 65 62 75 67 5f 68 6f |or_cert.debug_ho|
00232820 6f 6b 00 77 61 69 74 5f 66 6f 72 5f 64 65 62 75 |ok.wait_for_debu|
Which is a uint32_t that's 0x024fff and then a perfectly normal string
table that starts with, that's right, .eh_frame. And if you add that
length up you get 0x2577e5. And sure enough:
002577c0 61 72 69 61 62 6c 65 5f 64 61 74 61 00 6f 73 73 |ariable_data.oss|
002577d0 6c 5f 64 65 72 5f 6f 69 64 5f 63 32 74 6e 62 31 |l_der_oid_c2tnb1|
002577e0 39 31 76 31 00 |91v1.|
002577e5
That's the end of the binary.
tl;dr: there's 394KiB hanging around at the end of this binary, and the
only thing that's using it is using it is objdump, which is using... 49
bytes of it to show us section names.
This patch strips the COFF symbol table entirely, and replaces the COFF
string table with one that includes only the section names.
Signed-off-by: Peter Jones <pjones@redhat.com>
This moves all of the flags for post-process-pe to POST_PROCESS_PE_FLAGS and sets a default of "-c -vv" in Make.defaults. Signed-off-by: Peter Jones <pjones@redhat.com>
vathpela
force-pushed
the
strip-coff-symtabs
branch
from
July 27, 2026 20:46
79d7974 to
a52a4db
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #815 +/- ##
==========================================
- Coverage 59.48% 58.77% -0.71%
==========================================
Files 24 24
Lines 4226 4226
Branches 655 655
==========================================
- Hits 2514 2484 -30
Misses 1471 1471
- Partials 241 271 +30 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
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.
This PR addresses two issues in
post-process-pe:objdump -hand (now)post-process-peoutput.This PR adds code to show the section names, and also an option to strip the COFF symbol table and re-write the COFF string table to only include our section names.