0

Is there any way to explicitly do name mangling (also called name decoration) in a library written in c(or cpp).I want all the symbols of my shared library to have their names mangled.

Consider this question: Two library of different versions in an application In this if I can explicitly have all their names mangled , I think i can resolve that issue.May be there is some option in gcc compiler itself to do this.

  • Basically your proposed "name mangling" is the same as that proposed in the comments of your other question: rename the symbols in one of the libraries. You already rejected that. – Andrew Henle Jul 16 '19 at 14:10
  • 3
    XY problem? Why are you trying to mangle things? – SergeyA Jul 16 '19 at 14:17
  • C doesn’t support name mangling. You can probably do it in C++. – Jonathan Leffler Jul 16 '19 at 14:31
  • @AndrewHenle I didnt reject that idea. Actually the only way i know is by using --default-symver , and --default-symver is not exactly name mangling. And i dont want to rename all function in my code. I need something which can do symbol rename or name mangling , without much code changes. – Abhishek Garg Jul 16 '19 at 17:57
  • @SergeyA i need name mangling as the solution to the problem https://stackoverflow.com/questions/56947406/two-library-of-different-versions-in-an-application – Abhishek Garg Jul 16 '19 at 17:58
  • @JonathanLeffler can u kindly state how can we do in cpp – Abhishek Garg Jul 16 '19 at 17:59
  • @AbhishekGarg *I didnt reject that idea.* You most certainly did reject renaming symbols: " If I add my_ in front of all symbols , I have to make changes in A.1.so and B.so , and that changes will be really huge.This change is no better than dlopen().I need something which can make this thing work with minimal changes." The only difference between this question and that suggestion that you rejected is the replacement of "rename symbols" with "name mangling". You're casting about for a way to stuff two versions of the same library - with many overlapping symbols - into one process. – Andrew Henle Jul 16 '19 at 18:37
  • *i need name mangling as the solution to the problem https://stackoverflow.com/questions/56947406/two-library-of-different-versions-in-an-application* That makes this a duplicate of that question. – Andrew Henle Jul 16 '19 at 18:46
  • If you (can) compile the code as C++ and there are no `extern "C"` portions, then C++ will automatically mangle the names for you. If the library names overlap, then as long as you have the source to at least one of the libraries, you can deal with the issue by wrapping the library code in `namespace libname_3_14_1593 {` … `}` to make the names be in a new, name-versioned namespace. That's all I meant by my comment. – Jonathan Leffler Jul 16 '19 at 22:06
  • @AndrewHenle okay i realize my mistake. I thought he meant to say to rename all functions.I didnt had any idea of name mangling at that time. How can I prepend my_ to all external symbols – Abhishek Garg Jul 17 '19 at 03:26
  • @JonathanLeffler okay namespace is a good idea but i was looking more easy with less code change,and the code is actually written in c , so i cannot use that – Abhishek Garg Jul 17 '19 at 03:28
  • If the code is in C, you're stuck — C doesn't support name mangling (sensibly). You can write a header that mangles somehow every externally visible symbol in each library and use that, but it isn't a good solution. I'm not clear why you want to try to do this. – Jonathan Leffler Jul 17 '19 at 05:55
  • @JonathanLeffler i am trying all this as a part to the solution https://stackoverflow.com/questions/56947406/two-library-of-different-versions-in-an-application . Anyway " You can write a header that mangles somehow every externally visible symbol in each library and use that" ---- How to do this.Are u thinking using namespace – Abhishek Garg Jul 17 '19 at 13:36
  • I'm not thinking of 'using namespace' any more; you're working in C. But you could arrange for a header that contains multiple lines like `#define symbol1 libA_2_6_symbol1` to map the name `symbol1` from library A (version 2.6) to the new name `libA_2_6_symbol1` — rinse and repeat for every symbol in library A version 2.6. The code for the library would need to include that header (early enough in each compilation unit to be useful), and the code that uses the material from library A version 2.6 would need to be compiled with that header too. _[…continued (1)…]_ – Jonathan Leffler Jul 19 '19 at 21:07
  • _[…continuation (1)…]_ You could run the `nm` program to get the externally defined symbol names and use a `sed` script to rewrite them. A more sophisticated mapping would use function-like macros instead of object-like macros; that is a good idea, but tracking the function call argument lists could be painful (though I suppose `#define symbol1(...) libA_2_6_symbol1(__VA_ARGS__)` would do the job with minimal checking, but since the code already works, minimal checking should be adequate. You'd need to capture functions separately from variables. _[…continued (2)…]_ – Jonathan Leffler Jul 19 '19 at 21:11
  • _[…continuation (2)…]_ If you need to be able to have code calling both this version and another version of the same library, then you need to keep the two sets of calls to the library in separate files (so that each can be compiled with the correct library), and then use glue code to call both versioned libraries. It's a mess — it isn't what you should be doing. It may be what you have to do, though. And no, the C compiler isn't going to help much, IMO. You can look at the GNU C library versioning mechanisms to see if they help you, but I expect that they won't. – Jonathan Leffler Jul 19 '19 at 21:13

1 Answers1

1

Your question is:

Is there any way to explicitly do name mangling (also called name decoration) in a library written in c(or cpp).I want all the symbols of my shared library to have their names mangled.

However, I suspect that you're using the term name mangling inappropriately. Name mangling has nothing to do with library release version. If you mean to version each object exported in your library, then there are plenty of questions to answer that. Personally, I would use a versioned namespace -- but only because I haven't (yet) been bitten by it. Here's a quick example:

namespace mylibrary {
namespace v1 {
class foo {};
}
using foo = v1::foo;
}

mylibrary::foo f; // mylibrary::v1::foo

...then on a later release...

namespace mylibrary {
namespace v1 {
class foo {};
}
namespace v2 {
class foo;
}
using foo = v2::foo;
}
mylibrary::foo newer_f; // mylibrary::v2::foo
mylibrary::v1::foo older_f;

There are of course many permutations you could have. And there are a lot of caveats, especially if you have templated code or make use of ADL. If you release version 1 of the library with one definition of class foo but then version 2 has a different definition, then the two libraries will not be compatible! That's rather the whole point though.

If however I am incorrect and you truly do want to enforce C++ name mangling in your C++ library (which is odd, because it should be done by default), then the answer is twofold. First, take a look at some related questions:

The reading is related but not causal. The related questions are answering your question in reverse.

Many operating systems are written in C and that is typically why you'd see extern "C" when including system headers. It's also why you sometimes see the linker complaining about missing functions when you try to use things declared in a header whose library was compiled with C instead of C++.

So to go in the other direction (in your direction): in your header file, you can declare your exports to be extern "C++". That tells the compiler to specifically use mangled names when importing or exporting the object.

Using extern "C++" won't by itself be your magic trick. There are some GCC options which control some of the more specific functionality about name mangling. So, secondly, take a look at those. The (external link) to the GCC manual page is here: https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html

Any option which mentions ABI, such as -fabi, might impact you. "-fabi" flags relate to "Application Binary Interface". You might want to learn more about these terms too. What is an application binary interface has some excellent answers describing what an ABI is and how you can start to reason about them. "-Wabi" will tell GCC to emit warnings when it detects potential ABI conflicts. But, like all things C++, it's not foolproof. I would not be surprised if there are name mangling issues which might not be detected by it. That's particularly true if you ever mix heterogenous compiler vendors or versions.

Importantly: mixing ABIs is likely going to be a big headache. I'd be very concerned about ABI incompatibilities being forced together and causing very difficult-to-debug undefined behaviors!

inetknght
  • 4,300
  • 1
  • 26
  • 52