This is an archive of the discontinued LLVM Phabricator instance.

[LLD] [COFF] Allow using custom .edata from input object files
ClosedPublic

Authored by mstorsjo on Aug 7 2019, 1:50 PM.

Details

Summary

This is used by Wine for manually crafting export tables.

If the input object contains .edata sections, GNU ld references them in the export directory instead of synthesizing an export table using either export directives or the normal auto export mechanism. (AFAIK, historically, way way back, GNU ld didn't support synthesizing the export table - one was supposed to generate it using dlltool and link it in instead.)

If faced with --out-implib and --output-def, GNU ld still populates those output files with the same export info as it would have generated otherwise, disregarding the input .edata. As this isn't an intended usage combination, I'm not adding checks for that in tests.

Diff Detail

Repository
rL LLVM

Event Timeline

mstorsjo created this revision.Aug 7 2019, 1:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 7 2019, 1:50 PM
ruiu added a comment.Aug 8 2019, 1:16 AM

Is this due to the historical reason that wine is creating an .edata section instead of -export directive? I feel like this feature is obscure, and if there's a way to avoid adding this, I'd like to try that first. If GNU ld is fine with -export directive now, and wine's source code can be updated to use the directive (which is I believe a good refactoring as it would simplify the code), can wine's code be updated?

Is this due to the historical reason that wine is creating an .edata section instead of -export directive? I feel like this feature is obscure, and if there's a way to avoid adding this, I'd like to try that first. If GNU ld is fine with -export directive now, and wine's source code can be updated to use the directive (which is I believe a good refactoring as it would simplify the code), can wine's code be updated?

Wine supports building modules both as ELF and PE, and in ELF they generate the .edata manually, so they still need to keep that around, so using export directives isn't a simplification, it's yet another extra codepath.

And if I understood @jacek correctly, there was some case with relay stubs that don't map trivially to export directives.

While this is a very obscure feature, the implementation of it in lld turned out to be very straightforward (kind of like .idata chunks from long import libs, but much simpler).

ruiu added a comment.Aug 8 2019, 2:52 AM

I agree with you that this implementation is straightforward and simple, and I'm fine to add this if changing wine is not easy.

Could you add a little bit of comment to the code to explain what this is for?

Do you think it makes sense to show a warning if both -export and .edata are used?

I agree with you that this implementation is straightforward and simple, and I'm fine to add this if changing wine is not easy.

We discussed it with the Wine maintainer already, and he preferred this approach over using export directives.

Could you add a little bit of comment to the code to explain what this is for?

Sure, I can do that.

Do you think it makes sense to show a warning if both -export and .edata are used?

That would probably make sense. Unfortunately, I think we only know whether we have custom .edata at the end, after we've autoexported all symbols (if no export directives were found), but I can store a bool to distinguish between the cases.

mstorsjo updated this revision to Diff 214106.Aug 8 2019, 4:06 AM

Added a comment, and a warning if there's both .edata sections and explicit exports. Adjusted the testcase to test the warning. Adjusted how the edata size is calculated, to account for potential alignment padding.

ruiu added inline comments.Aug 19 2019, 10:32 PM
COFF/Writer.cpp
1026–1029 ↗(On Diff #214106)

Do you have to use these two variables?

1376 ↗(On Diff #214106)

Looks like you can check if !edataSec->chunks.empty() here and use edataSec->chunks.front() and back() in the following lines.

mstorsjo marked an inline comment as done.Aug 19 2019, 10:36 PM
mstorsjo added inline comments.
COFF/Writer.cpp
1376 ↗(On Diff #214106)

No, I can't. Edata ends up merged into rdata, so at this point, edataSec is empty.

ruiu accepted this revision.Aug 19 2019, 10:40 PM

LGTM

This revision is now accepted and ready to land.Aug 19 2019, 10:40 PM
This revision was automatically updated to reflect the committed changes.