Non-reproducible binaries generated by GenFw


Ross Burton <ross@...>
 

Hi,

As per https://bugzilla.tianocore.org/show_bug.cgi?id=3256, GenFw
writes non-reproducible binaries by embedding a build path. In fact in
a build of ovmf with embedded shell, this one path is the sole source
of non-determinism.

WriteDebug64() is always called in GenFw on output and that embeds
into the NB10 entry the input filename. As build paths change this is
a source of non-determinism. There already exists a --zero option to
wipe out debug paths but this is in release builds so I'm not sure
what the best solution is. I can see several options:

1) Release builds should not call WriteDebug64() at all
2) --zero should wipe the NB10 entry, and release builds should pass that
3) GenFw should support path remapping (like gcc's -ffile-prefix-map)
to turn build paths into something consistent.

Any suggestions?

Cheers,
Ross


Andrew Fish
 

On Mar 10, 2021, at 11:36 AM, Ross Burton <ross@...> wrote:

Hi,

As per https://bugzilla.tianocore.org/show_bug.cgi?id=3256, GenFw
writes non-reproducible binaries by embedding a build path. In fact in
a build of ovmf with embedded shell, this one path is the sole source
of non-determinism.

WriteDebug64() is always called in GenFw on output and that embeds
into the NB10 entry the input filename. As build paths change this is
a source of non-determinism. There already exists a --zero option to
wipe out debug paths but this is in release builds so I'm not sure
what the best solution is. I can see several options:

1) Release builds should not call WriteDebug64() at all
2) --zero should wipe the NB10 entry, and release builds should pass that
3) GenFw should support path remapping (like gcc's -ffile-prefix-map)
to turn build paths into something consistent.

Any suggestions?
This is kind of a tangent, but for clang we solved a similar problem a different way.
1) in the build_rule.txt file we added a cd $(WORKSPACE); on the compile line so __FILE__ is always relative to the $(WORKSPACE);
2) We added a post build step to create a Symbols directory in the Build output.
a) The debug directory entry paths are relative to that symbols directory. They generally look like IA32/PeiCore or X64/DxeCore etc.
b) In the old days we would launch the debugger from the Symbols directory so relative files got searched relative to the symbols directory.
c) Now we use the UUID we have in the EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY[1]PE/COFF debug entry. On a Mac these mach-O UUIDs are automatically indexed by Spotlight so the debugger can just find them. It is also possible to write a tool to lookup these UUIDs that makes them available to the debugger.

I’m not sure it is possible to do something like this with all the toolchains, but I wanted to at least let people know we figured out a way with clang.

[1] https://github.com/tianocore/edk2/blob/master/MdePkg/Include/IndustryStandard/PeImage.h#L659

Thanks,

Andrew Fish

Cheers,
Ross