-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extended COFF format (/bigobj) support #65
Conversation
What is the status on this PR? Having support for |
I had started a review to try to reduce some of the magic offset numbers. The main thing blocking it for me is a test case: both to verify myself that it works and to be able to continuous verify that it works in CI. At the moment I have to read up on how to generate one of these, generate it and figure out how to test for it in CI... none of which I mind having to do some day, but if it iwere to appear by magic, I'd be able to finish reviewing faster 🙂 |
Doesn't the pull request already include some kind of mini test by compiling |
Ah: somehow I'd seen the first bit, and not noticed that it was plumbed in in |
Hmm, the original code contains those magic offsets as well. How are going to get rid of them? Replace by symbolic names? As for tests - yes I was too lazy to create them :( Do you have any idea how to correctly test /bigobj functionality (especially for CI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There were some minor refactorings - mainly to have slightly fewer names for numbers (I'd mis-characterised what I'd got before).
There are a couple of questions about the changes to the header reading.
For testing - does the current test definitely exercise the code which writes the new ECOFF file and is it then read back by another part of the test? (i.e. do we effectively do a round-trip of the file somewhere in amongst!).
Assuming that is the case, I think all that needs to happen is to do one test on MSVC with /bigobj
and another without, which should be an easy tweak.
Because of #94, flexdll 0.40 will be released soon - as long as I can convince myself that the changes here definitely don't affect the normal COFF case (that's the basis for the questions about the version number reading following the \000\000\255\255
header) then I think this can (finally) be included, thanks!
let get strtbl ic pos = | ||
let buf = read ic pos 18 in | ||
let auxn = int8 buf 17 in | ||
let get bigobj strtbl ic pos = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let get bigobj strtbl ic pos = | |
let get ~bigobj strtbl ic pos = |
(boolean flags are very unclear - I realise there are others already in the code!)
@@ -397,7 +402,12 @@ module Symbol = struct | |||
"value=0x%08lx, sect=%s, storage=%s, aux=%S\n" | |||
s.value sect storage (Bytes.to_string s.auxs) | |||
|
|||
let put strtbl oc s = | |||
let put bigobj strtbl oc s = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let put bigobj strtbl oc s = | |
let put ~bigobj strtbl oc s = |
(as for get
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's wrong with using the label here?! ~bigobj:x.bigobj
?
emit_int16 oc 0; (* Sig1 *) | ||
emit_int16 oc 0xffff; (* Sig2 *) | ||
emit_int16 oc 2; (* Version *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this written on this side (for bigobj) but not on the other (for the legacy one)?
There may well be a reason, I was just scratching my head trying to work it out!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I address your other comments later (they're mostly cosmetic and I have nothing against them. I tried to change the original sources minimally while you're trying to make them more readable). Regarding this:
https://github.com/alainfrisch/flexdll/blob/f40ed2d57bbb70ac8223d30a6ffa737f2c0e430e/coff.ml#L856-L873
I don't quite understand your question. Why Sig1, Sig2, and Version are not emitted for the standard COFF? Just because its header does not include these fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This makes sense to me now w.r.t. the comment below - I hadn't registered properly that what we had before was an incorrect reading of an ECOFF header (assuming an import library)
@@ -859,11 +946,17 @@ module Lib = struct | |||
let obj size name = | |||
(* Printf.printf "-> %s (size %i)\n" name size; *) | |||
let pos = pos_in ic in | |||
if size > 18 && read_str ic pos 4 = "\000\000\255\255" | |||
then imports := Import.read ic pos size :: !imports |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this an error before - having ascertained that the magic header was there, shouldn't have read the version, instead doesn't it get lumped onto the first symbol?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sort of. This check would treat ANON_OBJECT_HEADER_BIGOBJ as IMPORT_OBJECT_HEADER (i.e. an import library). I didn't try to feed bigobj files to the current version of flexlink but suppose it will fail somewhere instead of showing an informative error message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see now (sorry, I could also have scoured the COFF spec, too) - what we had before was an assumption that the \000\000\255\255
header implied strictly an object library whereas now we actually read the header properly. Gotcha!
(please could you rebase it on to current master, too) |
…esting for bigobj support
Co-authored-by: David Allsopp <david.allsopp@metastack.com>
You'll also want something like dra27@31e835f, I'm afraid! |
OK, I'll do that. Thanks! |
I have the start of a plan to overhaul the way |
Is there a quick test which could be extracted from that? As long as there aren't too many OCaml dependencies, CI already has an OCaml compiler available, so if there's something which can relatively quickly be built, it's always good to have more tests! Obviously, the test doesn't have to run on the entire matrix... |
I'll add /bigobj-enabled demo_msvc build to CI. But Appveyor is ridiculously laggy, so I have to wait another hour for the previous commit CI job to complete... |
Fortunately, once the AppVeyor build of master has finished the caches will all be primed, so the next build should be quite a bit quicker! We've (at OCaml Labs) nearly got our Windows build cluster up and running... I'm hoping to replace the AppVeyor CI with a rather more parallel one on that! |
@dra27 I think I've addressed all your comments (except labeling |
@@ -207,7 +207,7 @@ flexdll_initer_mingw64.o: flexdll_initer.c | |||
|
|||
|
|||
demo_msvc: flexlink.exe flexdll_msvc.obj flexdll_initer_msvc.obj | |||
$(MSVC_PREFIX) $(MAKE) -C test clean demo CHAIN=msvc CC="$(MSVCC)" O=obj | |||
$(MSVC_PREFIX) $(MAKE) -C test clean demo CHAIN=msvc CC="$(MSVCC)" BIGOBJ="/bigobj" O=obj |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These need removing now, I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh, I've just forgot what I did 3 years ago :( My last commit adding
https://github.com/alainfrisch/flexdll/blob/4da3dac05d715f25a27d7b56bc37d9dde09e37f6/appveyor_build.sh#L168-L170
is useless, /bigobj test was already there (added in 7ccf31b). Will drop the last commit instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the original commit you want to drop - I'd prefer it to be that the test msvc and msvc64 by default do not test /bigobj but that AppVeyor runs those tests twice, once with and once without (which I think is what's then happening here?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's the original commit you want to drop - I'd prefer it to be that the test msvc and msvc64 by default do not test /bigobj
Why? 3 years ago I decided to test COFF/ECOFF simultaneously: for MSVC plug1.c is compiled without /bigobj and plug2.c with /bigobj.
but that AppVeyor runs those tests twice, once with and once without (which I think is what's then happening here?)
Yes, the last commit effectively runs the same test twice, that's why I'm going to drop it.
I think there's an old part in the test |
Thanks very much! |
Looks like it works now. Actually, ECOFF is not very different from COFF: it uses another file header (ANON_OBJECT_HEADER_BIGOBJ, see winnt.h in Windows SDK) and allows more than 2^16 sections in a single file (
NumberOfSections
header field. has tipeDWORD
)