Skip to content
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

NSZone Selector Missmatch #297

Open
hmelder opened this issue Aug 14, 2024 · 3 comments
Open

NSZone Selector Missmatch #297

hmelder opened this issue Aug 14, 2024 · 3 comments

Comments

@hmelder
Copy link
Collaborator

hmelder commented Aug 14, 2024

The NSZone stub here has in a different signature which results in a warning at runtime when passing a gnustep-base NSZone struct to objc_allocWithZone: (@24@0:8^{_NSZone=^?^?^?^?^?^?^?Q@^{_NSZone}}16), selector has @24@0:8^{_NSZone=}16.

@davidchisnall how about changing the NSZone struct in fast_path.m to follow the same layout as in gnustep-base?

@davidchisnall
Copy link
Member

Hmm, this is a special case of a general problem that we should probably fix:

If one compilation unit has a selector that takes a pointer to a forward-declared structure and another has one that takes a pointer to the same forward-declared structure but can see the definition, their types will not match. This is likely to be true for anything where structures are handed out as opaque types.

The right solution here is probably to have the selector hashing code skip everything between the = and } in pointers to structures (not in structures passed by value. We should hash ^{_NSZone=^?^?^?^?^?^?^?Q@^{_NSZone} and ^{_NSZone=} to the same value, but also make sure that (for example) {_NSZone=^?^?^?^?^?^?^?Q@^{_NSZone} and {_NSZone=I} hash to different values.

@hmelder
Copy link
Collaborator Author

hmelder commented Sep 8, 2024

The right solution here is probably to have the selector hashing code skip everything between the = and } in pointers to structures

Good idea. Let's merge #298 first to avoid merge conflicts later on :)

@hmelder
Copy link
Collaborator Author

hmelder commented Nov 12, 2024

The right solution here is probably to have the selector hashing code skip everything between the = and } in pointers to structures

But we also need to take care of SelectorEquals used in

using SelectorTable = tsl::robin_set<objc_selector*, SelectorHash, SelectorEqual>;
. Otherwise, the hash set will not consider the two selectors to be equal.

Apple just takes the address of the selector as hash, as all selectors are uniqued in __objc_selref, and does not emitting a new typed selector in a compilation unit that does not contain the implementation. Instead, an undefined stub of the form objc_msgSend$<SEL_NAME> is emitted. The actual thunk which retrieves the selector from objc_selref and calls objc_msgSend is generated by ld64.

That is not really an option for us as this requires a contract with the linker.

So I guess doing it at runtime is the best option at the expense of a more complex selector hashing and equality routine. Are we ok with that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

2 participants