[PATCH] D89518: [windows-itanium] Add Windows Itanium How-To Guide

ben via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 25 09:08:01 PST 2020


bd1976llvm added inline comments.


================
Comment at: llvm/docs/HowToBuildWindowsItaniumPrograms.rst:57
+there is no declaration available to the compiler so this can't be done. To allow
+programs to link we currently rely on the -lldmingw switch in LLD to auto-import
+references to __cxxabiv1::__class_type_info pointers (see: https://reviews.llvm.org/D43184
----------------
bd1976llvm wrote:
> mstorsjo wrote:
> > bd1976llvm wrote:
> > > mstorsjo wrote:
> > > > bd1976llvm wrote:
> > > > > mstorsjo wrote:
> > > > > > Fwiw, since release 11, you can enable autoimporting alone without enabling the rest of the mingw specific quirks, with the `-autoimport` flag. Also see D89006 for a recent related fixup.
> > > > > Thanks. This is a nice improvement!
> > > > It seems nicer, yes, but it also gives the false impression that you can enable and use it without the corresponding mingw runtime, so that's not ideal either. I'm pondering if I should spend more effort on making it harder to fall into that trap.
> > > Interestingly, If I try to use -auto-import in LLD it does diagnose the problem. I see errors like:
> > > 
> > > "lld-link: error: automatic dllimport of _ZTVN10__cxxabiv117__class_type_infoE in plugin-f2d5e0.o requires pseudo relocations"
> > > 
> > > This doesn't seem to happen with -lldmingw.
> > Ah, that's right.
> > 
> > Yes, the feature is split up into two separate feature flags. `-autoimport` handles the aspect of looking for `__imp_<symbol>` if `<symbol>` is needed but missing. An autoimported variable may or may not need a pseudo relocation.
> > 
> > If the reference to the autoimported variable is in a pointer-sized section chunk, with the relocation being storing the absolute address of the variable, then lld can skip doing the pseudo relocation, and redirect all accesses from that section chunk towards the `__imp_<symbol>` symbol instead (which is a plain pointer that will contain the real address of the symbol at runtime). When compiling code for a mingw target, llvm generates indirection via such stubs (if you read code, `COFFSTUB` is used to refer to this), e.g. like this:
> > ```
> > $ cat test.c
> > extern int maybeImported;
> > int getter(void) {
> >   return maybeImported;
> > }
> > $ clang -target x86_64-windows-gnu -S -o - test.c
> > [...]
> > getter:
> >         movq    .refptr.maybeImported(%rip), %rax
> >         movl    (%rax), %eax
> >         retq
> > 
> >         .section        .rdata$.refptr.maybeImported,"dr",discard,.refptr.maybeImported
> >         .globl  .refptr.maybeImported
> > .refptr.maybeImported:
> >         .quad   maybeImported
> > ```
> > 
> > This is done for all accesses to global variables that aren't defined in the same translation unit. If the variable turns out to exist in the same DLL, it produces one pointer sized data block that contains a pointer to the function - if the variable turns out to need to be imported, the whole section ends up thrown away, and all accesses go to the `__imp_<symbol>` pointer instead, which behaves exactly like that one.
> > 
> > That works fine for cases where code accesses variables, but if you have a pointer in a structure next to other things, lld can't do that:
> > ```
> > $ cat test2.c
> > extern int maybeImported;
> > struct {
> >     int foo;
> >     int *ptr;
> >     int bar;
> > } mystruct = {
> >     42,
> >     &maybeImported,
> >     43
> > };
> > $ clang -target x86_64-windows-gnu -S -o - test2.c
> >         .data
> >         .globl  mystruct
> > mystruct:
> >         .long   42
> >         .zero   4
> >         .quad   maybeImported
> >         .long   43
> >         .zero   4
> > 
> > ```
> > 
> > So the cases with pointers in vtables, you really need psuedo relocations for that.
> Thanks! It would be great to add a test-case to show this limitation with the current implementation. I suppose that anything that relies on a type comparison is broken. I will have a play around and see if I can come up with some testcases.
I gave this a go and couldn't make a testcase that fails. I think that this is because the type_info class only has one virtual method - the destructor - and the destructors of type_infos are not called (the standard does seem to permit the destructors not to be called). Therefore, the fact that the vtable references are not fixed up correct in type_info objects is not functionally important.

I think that the "correct" Windows Itanium fix for this is to adopt a change very much like your https://reviews.llvm.org/D43184. However, I wonder if, as a work-around, we couldn't implement a constructor (in the sense of some code that runs as program initialisation time) for Windows Itanium that patches the mingw "pseudo relocations". This might be preferable as I would like to keep the patchset for Windows Itanium as minimal as possible.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89518/new/

https://reviews.llvm.org/D89518



More information about the llvm-commits mailing list