This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Remove _LIBCPP_ABI_BAD_FUNCTION_CALL_KEY_FUNCTION
AbandonedPublic

Authored by philnik on Jan 29 2023, 7:16 AM.

Details

Reviewers
ldionne
Mordante
daltenty
Group Reviewers
Restricted Project
Summary

In the stable ABI, the destructor was always defined inline, so all TUs have a weak definition of the symbols, which means that if the strong definition from the dylib is removed, there is still an equivalent weak definition available.
In the unstable ABI, there is still bad_function_call::what() as the key function, so there will be a strong definition of the symbols in the dylib and no weak definitions.

Diff Detail

Event Timeline

philnik created this revision.Jan 29 2023, 7:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 29 2023, 7:16 AM
philnik requested review of this revision.Jan 29 2023, 7:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 29 2023, 7:16 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik edited the summary of this revision. (Show Details)Jan 29 2023, 7:17 AM

Do you know why we have two key functions, which both require ABI v2?

libcxx/include/__functional/function.h
52–53

Why is this still needed?

ldionne requested changes to this revision.Feb 10 2023, 11:05 AM

I don't understand how that's not an ABI break. When _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE is not defined (i.e. in the stable ABI), we don't have a key function. https://reviews.llvm.org/D92397 may be interesting to consult for additional context.

This revision now requires changes to proceed.Feb 10 2023, 11:05 AM

I don't understand how that's not an ABI break. When _LIBCPP_ABI_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE is not defined (i.e. in the stable ABI), we don't have a key function. https://reviews.llvm.org/D92397 may be interesting to consult for additional context.

I never said it's not an ABI break. It's just that we already have bad_function_call::what() when the unstable ABI is enabled. We don't need two key functions.

So we just went over the patch again. Basically, this undoes the part of D92397 that unconditionally defines ~bad_function_call() in the dylib, but not the part that adds a separate setting for controlling whether bad_function_call::what() is defined in the dylib, and hence whether a key function is provided in the dylib.

In the stable ABI, before this patch:

  1. User code will always contain a weak definition of the bad_function_call vtable since we did not provide a key-function-declaration in the headers. Hence, no user code should contain hard references to bad_function_call's vtable, destructor or else. This was checked against the apps in the App Store, so I think our understanding is confirmed here.
  2. The dylib always provides a strong vtable that contains ~bad_function_call(), but not bad_function_call::what().

In the stable ABI, after this patch:

  1. User code will always contain a weak definition of the vtable too.
  2. The dylib won't provide a strong vtable for bad_function_call anymore, but that shouldn't be used today as noted above.

In the unstable ABI, before this patch, there was a strong vtable in the dylib with ~bad_function_call() and bad_function_call::what(), and users are relying on it. After the patch, it's the same thing except that we don't define ~bad_function_call() manually, we let the compiler do it.

After all these considerations, I think this is likely safe to do, and we'll indeed remove a few symbols from the dylib, and clean up our __config a bit. Please update the ABI list and explain the above in your commit message + in the ABI list change log. I'd like to see this one last time to double check before it goes out.

libcxx/src/functional.cpp
27

You will need to grep for Address Sanitizer doesn't instrument weak symbols on Linux. and adjust the UNSUPPORTED there. It should become something like UNSUPPORTED: asan && libcpp-abi-version=2.

philnik edited the summary of this revision. (Show Details)Feb 21 2023, 7:45 AM
philnik updated this revision to Diff 499179.Feb 21 2023, 7:54 AM
philnik marked 2 inline comments as done.

Address comments

libcxx/include/__functional/function.h
52–53

It's not.

libcxx/src/functional.cpp
27

IIUC this shouldn't be a problem anymore, since we don't have any weak symbols in ABIv2, and have only weak symbols in ABIv1 again.

daltenty requested changes to this revision.Feb 21 2023, 9:18 AM
daltenty added a subscriber: daltenty.

Unfortunately, some of this doesn't really work on AIX linkage model. Specifically, the linker doesn't follow the resolution semantic of trying to resolve weak references locally first that you see on other platforms (we have an option -bweaklocal to enable that), so we prefer the strong def we see in the library. This means this assumption doesn't hold on AIX:

  • User code will always contain a weak definition of the bad_function_call vtable since we did not provide a key-function-declaration in the headers. Hence, no user code should contain hard references to bad_function_call's vtable, destructor or else.

So removing the symbol from the dylib will break the ABI for us.

This revision now requires changes to proceed.Feb 21 2023, 9:18 AM

@philnik, can you update this to always have the key function on AIX and remove it for other platforms?

philnik abandoned this revision.May 23 2023, 2:34 PM