This is an archive of the discontinued LLVM Phabricator instance.

Make libc++'s versioning namespace customizable
ClosedPublic

Authored by EricWF on Oct 30 2018, 11:50 AM.

Details

Summary

This patch makes the versioning namespace libc++ uses customizable by the user using -DLIBCXX_ABI_NAMESPACE=__foo.

This allows users to build custom versions of libc++ which can be linked into binaries with other libc++ versions without causing symbol conflicts or ODR issues.

Diff Detail

Repository
rCXX libc++

Event Timeline

EricWF created this revision.Oct 30 2018, 11:50 AM

Awesome, I don't have to maintain an internal patch for this anymore :)

kristina added a subscriber: kristina.EditedOct 30 2018, 12:43 PM

LG, one suggestion, would it be possible to request the std:: namespace (disable inline namespaces altogether) by supplying a blank string?

Being able to avoid versioning is useful on embedded systems or any other systems that have a more controlled environment where only one libc++ is pretty much guaranteed? (this allows for compact mangling of certain types like std::string, which in turn saves a very significant amount of space as the full mangled name for it otherwise is fairly long and it appears in symbol tables and debug data for many kinds of template instantiations). Same applies to streams and some other types that have shorthand reserved mangled forms, at least with IA64 ABI.

If I understand correctly currently a blank string is simply ignored and __N form is used.

ldionne accepted this revision.Oct 30 2018, 1:55 PM
ldionne added inline comments.
CMakeLists.txt
685

__.+? Or do we want to allow __?

This revision is now accepted and ready to land.Oct 30 2018, 1:55 PM

LG, one suggestion, would it be possible to request the std:: namespace (disable inline namespaces altogether) by supplying a blank string?

Being able to avoid versioning is useful on embedded systems or any other systems that have a more controlled environment where only one libc++ is pretty much guaranteed? (this allows for compact mangling of certain types like std::string, which in turn saves a very significant amount of space as the full mangled name for it otherwise is fairly long and it appears in symbol tables and debug data for many kinds of template instantiations). Same applies to streams and some other types that have shorthand reserved mangled forms, at least with IA64 ABI.

If I understand correctly currently a blank string is simply ignored and __N form is used.

Yeah, that seems reasonable to me. I'll make the change.

CMakeLists.txt
685

In addition do we want _Foo. My thinking is we should probably allow users to foot-gun themselves as much as they want.

We should probably document that we make no promises that we don't introduce names which conflict with their custom namespace name.

ldionne added inline comments.Oct 30 2018, 2:07 PM
CMakeLists.txt
685

Actually, that's interesting. Another possibility would be to only allow users to use names that we can promise we won't reuse. For example we could say __x.+ is reserved for users, or something like that.

What we should really avoid is for someone to start using something like __3, which would conflict with something we want to use in the future. Even though it would be their problem in theory, in practice it might put pressure on us not to reuse the name (if it were an important vendor or something). Constraining what names they can use would clear this possibility out completely.

smeenai added inline comments.Oct 30 2018, 2:10 PM
CMakeLists.txt
685

I would strongly prefer the allowed names to not be that restricted, since existing custom inline namespaces might not confirm to it (our doesn't). Allowing __ followed by anything would work for us.

Maybe as a compromise restrict it to anything that isn't __[1-9] since I agree with the comments regarding arbitrary numbering making things difficult with regards to ABI evolution. For example a single letter would work and at the same time ensure it won't clash with future ABI versions.

EricWF updated this revision to Diff 171795.Oct 30 2018, 2:15 PM

LG, one suggestion, would it be possible to request the std:: namespace (disable inline namespaces altogether) by supplying a blank string?

Being able to avoid versioning is useful on embedded systems or any other systems that have a more controlled environment where only one libc++ is pretty much guaranteed? (this allows for compact mangling of certain types like std::string, which in turn saves a very significant amount of space as the full mangled name for it otherwise is fairly long and it appears in symbol tables and debug data for many kinds of template instantiations). Same applies to streams and some other types that have shorthand reserved mangled forms, at least with IA64 ABI.

If I understand correctly currently a blank string is simply ignored and __N form is used.

Yeah, that seems reasonable to me. I'll make the change.

Actually, I'll make the change as a follow up patch.

CMakeLists.txt
685

I've added a warning in the documentation that it's the responsibility of the user to choose a name that won't cause conflict, and that we make no promises. I think that's sufficient.

I've also weakened the error to a warning.

Actually, I'll make the change as a follow up patch.

Sounds good, I think a blank string, as a special case, explicitly being passed down fairly clearly conveys the intentions to opt out of inline namespaces and versioning.

ldionne requested changes to this revision.Oct 30 2018, 2:21 PM
ldionne added inline comments.
CMakeLists.txt
685

I disagree that documentation is sufficient. I understand your point (in theory), but in practice the consequences for someone misusing our API can be large enough that we have to deal with it. So in practice, we need to harden a bit more against misuse, especially when it's that easy. Please at least do what @kristina suggests and make sure that people are not using __[0-9]+.

This revision now requires changes to proceed.Oct 30 2018, 2:21 PM
ldionne added inline comments.Oct 30 2018, 2:23 PM
docs/BuildingLibcxx.rst
373

The problem with that is that they can't know what names we will want to use. If someone used __5 today, they would be within their rights because they can't know that we'll want to use it in the future. We have to reserve something for our own usage.

EricWF added inline comments.Oct 30 2018, 2:27 PM
docs/BuildingLibcxx.rst
373

We can't know what names we'll use in general. But they can be smart about it and aware of the risks.

EricWF updated this revision to Diff 171800.Oct 30 2018, 2:33 PM
  • Enforce that __[0-9]+$ is reserved.
ldionne accepted this revision.Oct 30 2018, 2:39 PM
This revision is now accepted and ready to land.Oct 30 2018, 2:39 PM
kristina added inline comments.Oct 30 2018, 2:40 PM
docs/BuildingLibcxx.rst
373

It's true but it's one of the things that one may not be aware of until suddenly a new ABI is rolled out that does cause a conflict. It makes sense for libc++ developers such as yourself to have a very small reserved namespace for "official" versioning changes. If people really want to risk shooting themselves in the foot they can edit the header, but something like __3 could be a ticking timebomb, and it's not always easy to understand why and it's better than breaking customer's code by accident as it's upstream after all, and it's much easier than write a long explanation on why __3 is a really bad idea but __a is okay.

This revision was automatically updated to reflect the committed changes.
jfoidart added a subscriber: jfoidart.EditedDec 12 2019, 5:17 PM

Actually, I'll make the change as a follow up patch.

Hi @EricWF . I checked the latest source and did not see such a change. Apologies if I missed it, but if not, is there still the plan to make this change? Thanks!