> On Sep 21, 2017, at 10:10 PM, Saleem Abdulrasool <compn...@compnerd.org> > wrote: > > On Thu, Sep 21, 2017 at 5:18 PM, John McCall <rjmcc...@apple.com > <mailto:rjmcc...@apple.com>> wrote: >> On Sep 21, 2017, at 1:26 PM, Saleem Abdulrasool via swift-dev >> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >> On Thu, Sep 21, 2017 at 12:04 PM, Joe Groff <jgr...@apple.com >> <mailto:jgr...@apple.com>> wrote: >> >> >>> On Sep 21, 2017, at 11:49 AM, Saleem Abdulrasool <compn...@compnerd.org >>> <mailto:compn...@compnerd.org>> wrote: >>> >>> On Thu, Sep 21, 2017 at 10:53 AM, Joe Groff <jgr...@apple.com >>> <mailto:jgr...@apple.com>> wrote: >>> >>> >>>> On Sep 21, 2017, at 9:32 AM, Saleem Abdulrasool via swift-dev >>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote: >>>> >>>> Hello, >>>> >>>> The current layout for the swift metadata for structure types, as emitted, >>>> seems to be unrepresentable in PE/COFF (at least for x86_64). There is a >>>> partial listing of the generated code following the message for reference. >>>> >>>> When building the standard library, LLVM encounters a relocation which >>>> cannot be represented. Tracking down the relocation led to the type >>>> metadata for SwiftNSOperatingSystemVersion. The metadata here is >>>> _T0SC30_SwiftNSOperatingSystemVersionVN. At +32-bytes we find the Kind >>>> (1). So, this is a struct metadata type. Thus at Offset 1 (+40 bytes) we >>>> have the nominal type descriptor reference. This is the relocation which >>>> we fail to represent correctly. If I'm not mistaken, it seems that the >>>> field is supposed to be a relative offset to the nominal type descriptor. >>>> However, currently, the nominal type descriptor is emitted in a different >>>> section (.rodata) as opposed to the type descriptor (.data). This >>>> cross-section relocation cannot be represented in the file format. >>>> >>>> My understanding is that the type metadata will be adjusted during the >>>> load for the field offsets. Furthermore, my guess is that the relative >>>> offset is used to encode the location to avoid a relocation for the load >>>> address base. In the case of windows, the based relocations are a given, >>>> and I'm not sure if there is a better approach to be taken. There are a >>>> couple of solutions which immediately spring to mind: moving the nominal >>>> type descriptor into the (RW) data segment and the other is to adjust the >>>> ABI to use an absolute relocation which would be rebased. Given that the >>>> type metadata may be adjusted means that we cannot emit it into the RO >>>> data segment. Is there another solution that I am overlooking which may >>>> be simpler or better? >>> >>> IIRC, this came up when someone was trying to port Swift to Windows on ARM >>> as well, and they were able to conditionalize the code so that we used >>> absolute pointers on Windows/ARM, and we may have to do the same on Windows >>> in general. It may be somewhat more complicated on Win64 since we generally >>> assume that relative references can be 32-bit, whereas an absolute >>> reference will be 64-bit, so some formats may have to change layout to make >>> this work too. I believe Windows' executable loader still ultimately maps >>> the final PE image contiguously, so alternatively, you could conceivably >>> build a Swift toolchain that used ELF or Mach-O or some other format with >>> better support for PIC as the intermediate object format and still linked a >>> final PE executable. Using relative references should still be a win on >>> Windows both because of the size benefit of being 32-bit and the fact that >>> they don't need to be slid when running under ASLR or when a DLL needs to >>> be rebased. >>> >>> >>> Yeah, I tracked down the relativePointer thing. There is a nice subtle >>> little warning that it is not fully portable :-). Would you happen to have >>> a pointer to where the adjustment for the absolute pointers on WoA is? >>> >>> You are correct that the image should be contiugously mapped on Windows. >>> The idea of MachO as an intermediatary is rather intriguing. Thinking >>> longer term, maybe we want to use that as a global solution? It would also >>> provide a nicer autolinking mechanism for ELF which is the one target which >>> currently is missing this functionality. However, if Im not mistaken, this >>> would require a MachO linker (and the only current viable MachO linker >>> would be ld64). The MachO binary would then need to be converted into ELF >>> or COFF. This seems like it could take a while to implement though, but >>> would not really break ABI, so pushing that off to later may be wise. >> >> Intriguingly, LLVM does support `*-*-win32-macho` as a target triple >> already, though I don't know what Mach-O to PE linker (if any) that's >> intended to be used with. We implemented relative references using >> current-position-relative offsets for Darwin and Linux both because that >> still allows for a fairly convenient pointer-like C++ API for working with >> relative offsets, and because the established toolchains on those platforms >> already have to support PIC so had most of the relocations we needed to make >> them work already; is there another base we could use for relative offsets >> on Windows that would fit in the set of relocations supported by standard >> COFF linkers? >> >> >> Yes, the `-windows-macho` target is used for UEFI :-). The MachO binary is >> translated later to PE/COFF as required by the UEFI specification. >> >> There are only two relocation types which can be used for relative >> displacements: __ImageBase relative (IMAGE_REL_*_ADDR32NB) and section >> relative (IMAGE_REL_*_SECREL) which are relative to the beginning of the >> section. The latter is why I mentioned that moving them into the same >> section could be a solution as that would allow the relative distance to be >> encoded. Unfortunately, the section relative relocation is relative to the >> section within which the symbol is. > > What's wrong with IMAGE_REL_AMD64_REL32? We'd have to adjust the > relative-pointer logic to store an offset from the end of the relative > pointer instead of the beginning, but it doesn't seem to have a section > requirement. > > Hmm, is it possible to use RIP relative addressing in data? If so, yes, that > could work.
There's no inherent reason, but I wouldn't put it past the linker to fall over and die. But it should at least be section-agnostic about the target, since this is likely to be used for all sorts of PC-relative addressing. John.
_______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev