Relative Pointers and Windows ARM


(Saleem Abdulrasool) #1

Hi,

It seems that there are assumptions about the ability to create relative
address across sections which doesn't seem possible on Windows ARM.

Consider the following swift code:

final class _ContiguousArrayStorage<Element> { }

When compiled for Windows x86 (via swiftc -c -target i686-windows
-parse-as-library -parse-stdlib -module-name Swift -o Swift.obj
reduced.swift) it will generate the metadata pattern as:

    __TMPCs23_ContiguousArrayStorage:
      ...
      .long
__TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
      ...

This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit
relative displacement of the target.

On Windows ARM (swiftc -c -target i686-windows -parse-pas-library
-parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will
generate similar assembly:

    _TMPCs23_ContiguousArrayStorage:
      ...
      .long
_TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
      ...

However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the
32-bit VA of the target. If the symbol are in the same section, it is
possible to get a relative value. However, I don't really see a way to
generate a relative offset across sections. There is no relocation in the
COFF ARM specification which provides the 32-bit relative displacement of
the target. There are 20, 23, and 24 bit relative displacements designed
specifically for branch instructions, but none that would operate on
generic data.

Is there a good way to address this ABI issue? Or perhaps do we need
something more invasive to support such targets? Now, I might be
completely overlooking something simple that I didn't consider, so pointing
that out would be greatly appreciated as well.

···

--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org


(Joe Groff) #2

That's unfortunate. One possibly-crazy solution would be to use a different object format that does support the necessary relocations, such as LLVM's win32-macho target. That would forgo interoperability with non-LLVM toolchains, of course.

-Joe

···

On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev <swift-dev@swift.org> wrote:

Hi,

It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.

Consider the following swift code:

final class _ContiguousArrayStorage<Element> { }

When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:

    __TMPCs23_ContiguousArrayStorage:
      ...
      .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
      ...

This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.

On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:

    _TMPCs23_ContiguousArrayStorage:
      ...
      .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
      ...

However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.

Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.


(John McCall) #3

You can build PIC on Windows ARM, right? How does Microsoft compile this:

  static int x;
  int *get_x_addr() { return &x; }

John.

···

On May 18, 2016, at 1:51 PM, Saleem Abdulrasool <compnerd@compnerd.org> wrote:
Hi,

It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.

Consider the following swift code:

final class _ContiguousArrayStorage<Element> { }

When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:

    __TMPCs23_ContiguousArrayStorage:
      ...
      .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
      ...

This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.

On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:

    _TMPCs23_ContiguousArrayStorage:
      ...
      .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
      ...

However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.

Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.


(Saleem Abdulrasool) #4

Yeah, it would make interoperability harder. But, is there a loader for
macho on Windows?

-Joe

···

On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com> wrote:

> On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev < > swift-dev@swift.org <javascript:;>> wrote:
>
> Hi,
>
> It seems that there are assumptions about the ability to create relative
address across sections which doesn't seem possible on Windows ARM.
>
> Consider the following swift code:
>
> final class _ContiguousArrayStorage<Element> { }
>
> When compiled for Windows x86 (via swiftc -c -target i686-windows
-parse-as-library -parse-stdlib -module-name Swift -o Swift.obj
reduced.swift) it will generate the metadata pattern as:
>
> __TMPCs23_ContiguousArrayStorage:
> ...
> .long
__TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> ...
>
> This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit
relative displacement of the target.
>
> On Windows ARM (swiftc -c -target i686-windows -parse-pas-library
-parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will
generate similar assembly:
>
> _TMPCs23_ContiguousArrayStorage:
> ...
> .long
_TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> ...
>
> However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the
32-bit VA of the target. If the symbol are in the same section, it is
possible to get a relative value. However, I don't really see a way to
generate a relative offset across sections. There is no relocation in the
COFF ARM specification which provides the 32-bit relative displacement of
the target. There are 20, 23, and 24 bit relative displacements designed
specifically for branch instructions, but none that would operate on
generic data.
>
> Is there a good way to address this ABI issue? Or perhaps do we need
something more invasive to support such targets? Now, I might be
completely overlooking something simple that I didn't consider, so pointing
that out would be greatly appreciated as well.

That's unfortunate. One possibly-crazy solution would be to use a
different object format that does support the necessary relocations, such
as LLVM's win32-macho target. That would forgo interoperability with
non-LLVM toolchains, of course

--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org


(Joe Groff) #5

I'm not familiar with Windows ARM, but if image loading works like Windows on Intel, then PIC isn't a thing—everything is compiled for a fixed address, and the kernel brute-force slides all the addresses at load time if it can't map an exe or dll at its preferred address.

-Joe

···

On May 19, 2016, at 9:07 AM, John McCall via swift-dev <swift-dev@swift.org> wrote:

On May 18, 2016, at 1:51 PM, Saleem Abdulrasool <compnerd@compnerd.org> wrote:
Hi,

It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.

Consider the following swift code:

final class _ContiguousArrayStorage<Element> { }

When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:

   __TMPCs23_ContiguousArrayStorage:
     ...
     .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
     ...

This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.

On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:

   _TMPCs23_ContiguousArrayStorage:
     ...
     .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
     ...

However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.

Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.

You can build PIC on Windows ARM, right? How does Microsoft compile this:

static int x;
int *get_x_addr() { return &x; }


(Saleem Abdulrasool) #6

> Hi,
>
> It seems that there are assumptions about the ability to create relative
address across sections which doesn't seem possible on Windows ARM.
>
> Consider the following swift code:
>
> final class _ContiguousArrayStorage<Element> { }
>
> When compiled for Windows x86 (via swiftc -c -target i686-windows
-parse-as-library -parse-stdlib -module-name Swift -o Swift.obj
reduced.swift) it will generate the metadata pattern as:
>
> __TMPCs23_ContiguousArrayStorage:
> ...
> .long
__TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> ...
>
> This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit
relative displacement of the target.
>
> On Windows ARM (swiftc -c -target i686-windows -parse-pas-library
-parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will
generate similar assembly:
>
> _TMPCs23_ContiguousArrayStorage:
> ...
> .long
_TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> ...
>
> However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the
32-bit VA of the target. If the symbol are in the same section, it is
possible to get a relative value. However, I don't really see a way to
generate a relative offset across sections. There is no relocation in the
COFF ARM specification which provides the 32-bit relative displacement of
the target. There are 20, 23, and 24 bit relative displacements designed
specifically for branch instructions, but none that would operate on
generic data.
>
> Is there a good way to address this ABI issue? Or perhaps do we need
something more invasive to support such targets? Now, I might be
completely overlooking something simple that I didn't consider, so pointing
that out would be greatly appreciated as well.

You can build PIC on Windows ARM, right? How does Microsoft compile this:

  static int x;
  int *get_x_addr() { return &x; }

It will generate what they call a based relocation, relying on the DLL
sliding to adjust for the load at an address other than the preferred base
address.

···

On Thu, May 19, 2016 at 9:07 AM, John McCall <rjmccall@apple.com> wrote:

> On May 18, 2016, at 1:51 PM, Saleem Abdulrasool <compnerd@compnerd.org> > wrote:

John.

--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org


(Joe Groff) #7

Sorry, if it wasn't clear, I meant that you could use mach-o (or ELF, or any object format really) for .o and .a files. You'd still link them into PE executables and DLLs.

-Joe

···

On May 18, 2016, at 6:01 PM, Saleem Abdulrasool <compnerd@compnerd.org> wrote:

On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com> wrote:

> On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev <swift-dev@swift.org> wrote:
>
> Hi,
>
> It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.
>
> Consider the following swift code:
>
> final class _ContiguousArrayStorage<Element> { }
>
> When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:
>
> __TMPCs23_ContiguousArrayStorage:
> ...
> .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> ...
>
> This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.
>
> On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:
>
> _TMPCs23_ContiguousArrayStorage:
> ...
> .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> ...
>
> However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.
>
> Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.

That's unfortunate. One possibly-crazy solution would be to use a different object format that does support the necessary relocations, such as LLVM's win32-macho target. That would forgo interoperability with non-LLVM toolchains, of course

Yeah, it would make interoperability harder. But, is there a loader for macho on Windows?


(John McCall) #8

Okay, so an absolute address and metadata to do a fix-up, i.e. not PIC. Score one for Joe.

I guess it's probably not reasonable to assume that IMAGE_REL_ARM_BRANCH24 will just work. :slight_smile: 16M is not really a reasonable max image size anyway.

Well, if we wanted to be adventurous, we could ask Microsoft to add an IMAGE_REL_ARM_REL32 relocation in a future toolchain. What we're asking of the ELF and Mach-O linkers isn't all that much less ridiculous... In the meantime, yeah, we should probably just switch to absolute addressing; it should be easy enough to generalize that in the metadata scheme.

John.

···

On May 19, 2016, at 5:39 PM, Saleem Abdulrasool <compnerd@compnerd.org> wrote:
On Thu, May 19, 2016 at 9:07 AM, John McCall <rjmccall@apple.com <mailto:rjmccall@apple.com>> wrote:
> On May 18, 2016, at 1:51 PM, Saleem Abdulrasool <compnerd@compnerd.org <mailto:compnerd@compnerd.org>> wrote:
> Hi,
>
> It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.
>
> Consider the following swift code:
>
> final class _ContiguousArrayStorage<Element> { }
>
> When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:
>
> __TMPCs23_ContiguousArrayStorage:
> ...
> .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> ...
>
> This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.
>
> On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:
>
> _TMPCs23_ContiguousArrayStorage:
> ...
> .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> ...
>
> However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.
>
> Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.

You can build PIC on Windows ARM, right? How does Microsoft compile this:

  static int x;
  int *get_x_addr() { return &x; }

It will generate what they call a based relocation, relying on the DLL sliding to adjust for the load at an address other than the preferred base address.


(Tom Birch) #9

Would it be acceptable to make relative pointers optional, so we can pay
the extra load-time cost on platforms where it's hard/undesirable to
implement them?

cheers,
Tom

···

On Thu, May 19, 2016 at 9:51 AM Joe Groff via swift-dev <swift-dev@swift.org> wrote:

> On May 18, 2016, at 6:01 PM, Saleem Abdulrasool <compnerd@compnerd.org> > wrote:
>
> On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com> wrote:
>
> > On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev < > swift-dev@swift.org> wrote:
> >
> > Hi,
> >
> > It seems that there are assumptions about the ability to create
relative address across sections which doesn't seem possible on Windows ARM.
> >
> > Consider the following swift code:
> >
> > final class _ContiguousArrayStorage<Element> { }
> >
> > When compiled for Windows x86 (via swiftc -c -target i686-windows
-parse-as-library -parse-stdlib -module-name Swift -o Swift.obj
reduced.swift) it will generate the metadata pattern as:
> >
> > __TMPCs23_ContiguousArrayStorage:
> > ...
> > .long
__TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> > ...
> >
> > This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit
relative displacement of the target.
> >
> > On Windows ARM (swiftc -c -target i686-windows -parse-pas-library
-parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will
generate similar assembly:
> >
> > _TMPCs23_ContiguousArrayStorage:
> > ...
> > .long
_TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> > ...
> >
> > However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is
the 32-bit VA of the target. If the symbol are in the same section, it is
possible to get a relative value. However, I don't really see a way to
generate a relative offset across sections. There is no relocation in the
COFF ARM specification which provides the 32-bit relative displacement of
the target. There are 20, 23, and 24 bit relative displacements designed
specifically for branch instructions, but none that would operate on
generic data.
> >
> > Is there a good way to address this ABI issue? Or perhaps do we need
something more invasive to support such targets? Now, I might be
completely overlooking something simple that I didn't consider, so pointing
that out would be greatly appreciated as well.
>
> That's unfortunate. One possibly-crazy solution would be to use a
different object format that does support the necessary relocations, such
as LLVM's win32-macho target. That would forgo interoperability with
non-LLVM toolchains, of course
>
> Yeah, it would make interoperability harder. But, is there a loader for
macho on Windows?

Sorry, if it wasn't clear, I meant that you could use mach-o (or ELF, or
any object format really) for .o and .a files. You'd still link them into
PE executables and DLLs.

-Joe
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(Joe Groff) #10

Would it be acceptable to make relative pointers optional, so we can pay the extra load-time cost on platforms where it's hard/undesirable to implement them?

That's also a reasonable answer, since sliding DLLs is already fairly costly. We'd need a bunch of extra tests to ensure both the relative and absolute forms work, though maybe with David Farler's work to abstract relative addresses it's already straightforward to have the RelativePointer<..> templates in the runtime work in a platform-independent way.

-Joe

···

On May 19, 2016, at 12:22 PM, Tom Birch <froody@gmail.com> wrote:

cheers,
Tom

On Thu, May 19, 2016 at 9:51 AM Joe Groff via swift-dev <swift-dev@swift.org> wrote:

> On May 18, 2016, at 6:01 PM, Saleem Abdulrasool <compnerd@compnerd.org> wrote:
>
> On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com> wrote:
>
> > On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev <swift-dev@swift.org> wrote:
> >
> > Hi,
> >
> > It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.
> >
> > Consider the following swift code:
> >
> > final class _ContiguousArrayStorage<Element> { }
> >
> > When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:
> >
> > __TMPCs23_ContiguousArrayStorage:
> > ...
> > .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> > ...
> >
> > This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.
> >
> > On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:
> >
> > _TMPCs23_ContiguousArrayStorage:
> > ...
> > .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> > ...
> >
> > However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.
> >
> > Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.
>
> That's unfortunate. One possibly-crazy solution would be to use a different object format that does support the necessary relocations, such as LLVM's win32-macho target. That would forgo interoperability with non-LLVM toolchains, of course
>
> Yeah, it would make interoperability harder. But, is there a loader for macho on Windows?

Sorry, if it wasn't clear, I meant that you could use mach-o (or ELF, or any object format really) for .o and .a files. You'd still link them into PE executables and DLLs.

-Joe
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev


(Saleem Abdulrasool) #11

>
> Would it be acceptable to make relative pointers optional, so we can pay
the extra load-time cost on platforms where it's hard/undesirable to
implement them?

That's also a reasonable answer, since sliding DLLs is already fairly
costly. We'd need a bunch of extra tests to ensure both the relative and
absolute forms work, though maybe with David Farler's work to abstract
relative addresses it's already straightforward to have the
RelativePointer<..> templates in the runtime work in a platform-independent
way.

Would be interesting to at least see if this is possible. Any hints on
where to get started with testing/prototyping such an approach?

···

On Thu, May 19, 2016 at 12:29 PM, Joe Groff <jgroff@apple.com> wrote:

> On May 19, 2016, at 12:22 PM, Tom Birch <froody@gmail.com> wrote:

-Joe

> cheers,
> Tom
>
> On Thu, May 19, 2016 at 9:51 AM Joe Groff via swift-dev < > swift-dev@swift.org> wrote:
>
> > On May 18, 2016, at 6:01 PM, Saleem Abdulrasool <compnerd@compnerd.org> > wrote:
> >
> > On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com> wrote:
> >
> > > On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev < > swift-dev@swift.org> wrote:
> > >
> > > Hi,
> > >
> > > It seems that there are assumptions about the ability to create
relative address across sections which doesn't seem possible on Windows ARM.
> > >
> > > Consider the following swift code:
> > >
> > > final class _ContiguousArrayStorage<Element> { }
> > >
> > > When compiled for Windows x86 (via swiftc -c -target i686-windows
-parse-as-library -parse-stdlib -module-name Swift -o Swift.obj
reduced.swift) it will generate the metadata pattern as:
> > >
> > > __TMPCs23_ContiguousArrayStorage:
> > > ...
> > > .long
__TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> > > ...
> > >
> > > This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit
relative displacement of the target.
> > >
> > > On Windows ARM (swiftc -c -target i686-windows -parse-pas-library
-parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will
generate similar assembly:
> > >
> > > _TMPCs23_ContiguousArrayStorage:
> > > ...
> > > .long
_TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> > > ...
> > >
> > > However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is
the 32-bit VA of the target. If the symbol are in the same section, it is
possible to get a relative value. However, I don't really see a way to
generate a relative offset across sections. There is no relocation in the
COFF ARM specification which provides the 32-bit relative displacement of
the target. There are 20, 23, and 24 bit relative displacements designed
specifically for branch instructions, but none that would operate on
generic data.
> > >
> > > Is there a good way to address this ABI issue? Or perhaps do we
need something more invasive to support such targets? Now, I might be
completely overlooking something simple that I didn't consider, so pointing
that out would be greatly appreciated as well.
> >
> > That's unfortunate. One possibly-crazy solution would be to use a
different object format that does support the necessary relocations, such
as LLVM's win32-macho target. That would forgo interoperability with
non-LLVM toolchains, of course
> >
> > Yeah, it would make interoperability harder. But, is there a loader
for macho on Windows?
>
> Sorry, if it wasn't clear, I meant that you could use mach-o (or ELF, or
any object format really) for .o and .a files. You'd still link them into
PE executables and DLLs.
>
> -Joe
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org


(John McCall) #12

>
> Would it be acceptable to make relative pointers optional, so we can pay the extra load-time cost on platforms where it's hard/undesirable to implement them?

That's also a reasonable answer, since sliding DLLs is already fairly costly. We'd need a bunch of extra tests to ensure both the relative and absolute forms work, though maybe with David Farler's work to abstract relative addresses it's already straightforward to have the RelativePointer<..> templates in the runtime work in a platform-independent way.

Would be interesting to at least see if this is possible. Any hints on where to get started with testing/prototyping such an approach?

Well, there are four places you need to worry about:
  - The parts of IRGen that emit constant relative references; these should all be using ConstantBuilder, so it should be easy to update them.
  - The parts of IRGen that emit code to dereference relative references; I'm not sure any of these actually exist right now.
  - The runtime, where like Joe says, it should be easy to abstract a template class on the runtime-traits class that's either a relative or absolute reference.
  - MetadataReader, which will need to do the right thing based on the runtime-traits class.

I think the hardest part of this is probably coming up with a pithy name. :slight_smile: It's important that callers not call something called addRelativeReference and have it just randomly add an absolute reference depending on target platform; the fact that it's sometimes relative and sometimes absolute is something that people adding new metadata features should be actively conscious of (among other things, because absolute references always have to be pointer-sized, not just 32 bits, and so the layout of the object may change). So we should call it something that doesn't directly connote absolute vs. relative: maybe NearReference or LocalReference?

John.

···

On May 21, 2016, at 1:01 PM, Saleem Abdulrasool via swift-dev <swift-dev@swift.org> wrote:
On Thu, May 19, 2016 at 12:29 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:
> On May 19, 2016, at 12:22 PM, Tom Birch <froody@gmail.com <mailto:froody@gmail.com>> wrote:

-Joe

> cheers,
> Tom
>
> On Thu, May 19, 2016 at 9:51 AM Joe Groff via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>
> > On May 18, 2016, at 6:01 PM, Saleem Abdulrasool <compnerd@compnerd.org <mailto:compnerd@compnerd.org>> wrote:
> >
> > On Wednesday, May 18, 2016, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:
> >
> > > On May 18, 2016, at 1:51 PM, Saleem Abdulrasool via swift-dev <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
> > >
> > > Hi,
> > >
> > > It seems that there are assumptions about the ability to create relative address across sections which doesn't seem possible on Windows ARM.
> > >
> > > Consider the following swift code:
> > >
> > > final class _ContiguousArrayStorage<Element> { }
> > >
> > > When compiled for Windows x86 (via swiftc -c -target i686-windows -parse-as-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate the metadata pattern as:
> > >
> > > __TMPCs23_ContiguousArrayStorage:
> > > ...
> > > .long __TMnCs23_ContiguousArrayStorage-(__MPCs23_ContiguousArrayStorage+128)
> > > ...
> > >
> > > This generates a IMAGE_REL_I386_REL32 relocation which is the 32-bit relative displacement of the target.
> > >
> > > On Windows ARM (swiftc -c -target i686-windows -parse-pas-library -parse-stdlib -module-name Swift -o Swift.obj reduced.swift) it will generate similar assembly:
> > >
> > > _TMPCs23_ContiguousArrayStorage:
> > > ...
> > > .long _TMnCs23_ContiguousArrayStorage-(_MPCs23_ContiguousArrayStorage+128)
> > > ...
> > >
> > > However, this generates an IMAGE_REL_ARM_ADDR32 relocation which is the 32-bit VA of the target. If the symbol are in the same section, it is possible to get a relative value. However, I don't really see a way to generate a relative offset across sections. There is no relocation in the COFF ARM specification which provides the 32-bit relative displacement of the target. There are 20, 23, and 24 bit relative displacements designed specifically for branch instructions, but none that would operate on generic data.
> > >
> > > Is there a good way to address this ABI issue? Or perhaps do we need something more invasive to support such targets? Now, I might be completely overlooking something simple that I didn't consider, so pointing that out would be greatly appreciated as well.
> >
> > That's unfortunate. One possibly-crazy solution would be to use a different object format that does support the necessary relocations, such as LLVM's win32-macho target. That would forgo interoperability with non-LLVM toolchains, of course
> >
> > Yeah, it would make interoperability harder. But, is there a loader for macho on Windows?
>
> Sorry, if it wasn't clear, I meant that you could use mach-o (or ELF, or any object format really) for .o and .a files. You'd still link them into PE executables and DLLs.
>
> -Joe
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org <mailto:swift-dev@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-dev

--
Saleem Abdulrasool
compnerd (at) compnerd (dot) org
_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev