-
-
Notifications
You must be signed in to change notification settings - Fork 421
[WIP] rt.sections_elf_shared: Add support for OSX (prepare for shared Phobos lib) #2322
Conversation
This is almost exactly LDC's version, which uses this module for 32/64-bit OSX too, incl. support for Phobos as shared library, and doesn't use `rt.sections_osx_x86[_64]` at all.
|
Thanks for your pull request and interest in making D better, @kinke! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. Bugzilla referencesYour PR doesn't reference any Bugzilla issue. If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog. Testing this PR locallyIf you don't have a local development environment setup, you can use Digger to test this PR: dub fetch digger
dub run digger -- build "master + druntime#2322" |
|
For this to work on OSX, DMD needs to be adapted. After a quick glance, this block would be needed for Mach-O objects too, in addition to
[I'm not going to implement that; no interest in the DMD backend. ;)] |
| @@ -36,6 +40,15 @@ else version (FreeBSD) | |||
| import core.sys.freebsd.sys.elf; | |||
| import core.sys.freebsd.sys.link_elf; | |||
| } | |||
| else version (OSX) | |||
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.
Not sure I understand when you're using SharedDarwin and when you're using OSX.
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.
Yeah I noticed the inconsistency too. It's not my code, and as you know, I have no interest in & knowledge of the different Mac OS flavours (desktop, iOS, watchOS, whatever).
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.
It is your code, you added SharedDarwin.
| void* start = null; | ||
| size_t size = 0; | ||
| _d_dyld_getTLSRange(tlsSymbol, &start, &size); | ||
| assert(start && size, "Could not determine TLS range."); |
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 check will be removed if asserts are removed, is that intentional?
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.
Most likely not => #2324.
| @@ -352,6 +388,12 @@ else | |||
| // Compiler to runtime interface. | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
|
|
|||
| version (OSX) | |||
| private alias ImageHeader = mach_header*; | |||
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.
Will this work for both 32bit and 64bit? There's a mach_header_64 type as well. I guess it will work as long as no fields are accessed.
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.
It does work for LDC, apparently for the reason you mentioned (used for _dyld_get_image_header_containing_address(), _dyld_get_image_slide() and LDC-specific hacky (pointer-casting) getSection(); the latter is available in the sections_osx_*.d files here and would need to be moved.]
Yeah, that's the big task 😃. |
It should be doable. My intention was to prepare the druntime side of it, so that DMD is the only blocker. I was hoping you specifically would be interested and knowledgeable enough to finally make DMD catch up with LDC in this regard ;) (and allow us to get rid of the LDC specifics in this file, which should probably be renamed to Btw, the ModuleInfos section range currently required for the compiler-generated DSO data is the reason for the linking errors you got with LLD (magic linker symbols); deriving them from the image headers would be nicer indeed. That should be pretty simple for OSX via Maybe there's a better way to obtain the TLS range for a specific thread than LDC's variant, one based on the image headers as for ELF... |
I'm definitely interested. If I'm knowledgeable enough that's a different question 😃. I would think I could handle the druntime side of it, i.e. basically what you have in this PR. But the compiler side, I'm not so sure. If the assembly is the same as for ELF, I could probably get the data into the correct sections for Mach-O but if the assembly is different then it would be much more difficult for me. Also there's the standard issue with the lack of time.
Cool. BTW, I know that DMD had problems in the past with bracketed sections and the linker messing them up. That's why DMD stopped using them when someone showed how easy it was to get access to a section. But I guess LDC doesn't have those problems since it's using LLVM. |
|
FYI, DMD only uses the native TLS implementation on macOS 64bit. On 32bit it still uses the old emulated TLS implementation. |
|
So @kinke , what's the status with this ? Still blocked on the DMD backend I suppose ? |
|
Yes. It should be feasible and simpler now without 32-bit x86 macOS support though (i.e., with native TLS). |
|
Incase it hasn't been said already, this module is in desperate need of a rename if you add Darwin support to it. |
| { | ||
| auto header = _dyld_get_image_header_containing_address(addr); | ||
| if (result) *result = header; | ||
| return !!header; |
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.
Without knowing this existed, I independently came up with this implementation for findDSOInfoForAddr:
foreach (i; 0 .. _dyld_image_count())
{
const header = _dyld_get_image_header(i);
const slide = _dyld_get_image_vmaddr_slide(i);
const section = getSection(header, slide, SEG_DATA, SECT_DATA);
// less than base address of section means quick reject
if (!section.length || addr < section.ptr)
continue;
if (addr < section.ptr + section.length)
{
result.header = header;
result.slide = slide;
return true;
}
}
return false;
Probably could align ourselves up, mixing what you have here with _dyld_get_image_vmaddr_slide for getting the slide value. So you don't have to rely on a private function later.
I think:
const header = _dyld_get_image_header_containing_address(addr);
if (header is null)
return false;
foreach (i; 0 .. _dyld_image_count())
{
if (header == _dyld_get_image_header(i))
{
result.header = header;
result.slide = _dyld_get_image_vmaddr_slide(i);
return true;
}
}
return false;
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.
On darwin9, and older versions, will have to use dladdr() instead (though realistically even supporting darwin8 (OSX 10.4) is a bit of a stretch).
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 PR is more than 2 years old - this now looks like this: https://github.com/ldc-developers/druntime/blob/a261a84e4c6b208c65ae39da0ae844ae3dd06744/src/rt/sections_elf_shared.d#L903-L907
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.
The slide can be calculated like this [1]. Also note this [2]:
"The following functions allow you to iterate through all loaded images. This is not a thread safe operation. Another thread can add or remove an image during the iteration.
Many uses of these routines can be replace by a call to dladdr() which will return the mach_header and name of an image, given an address in the image. dladdr() is thread safe."
[2] https://opensource.apple.com/source/dyld/dyld-750.6/include/mach-o/dyld.h.auto.html
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.
@jacob-carlborg good to know, though you're still using _dyld_image_count and get_image_header
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.
Yeah, IIRC I couldn't get that to work with dladdr.
|
Druntime have been merged into DMD. Please re-submit your PR to |
|
FYI I ended up naming these files after their object format (sections.macho, sections.elf, sections.pecoff), rather than trying to shoehorn it all into one place. All inevitable duplication then was moved over to a sections.common module. |
This is almost exactly LDC's version, which uses this module for 32/64-bit OSX too, incl. support for Phobos as shared library, and doesn't use
rt.sections_osx_x86[_64]at all.