Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to manually mangle names in Visual C++?

If I have a function in a .c like

void foo(int c, char v);

...in my .obj, this becomes a symbol named

_foo

...as per C name mangling rules. If I have a similar function in a .cpp file, this becomes something else entirely, as per the compiler-specific name mangling rules. msvc 12 will give us this:

?foo@@YAXHD@Z

If I have that function foo in the .cpp file and I want it to use C name mangling rules (assuming I can do without overloading), we can declare it as

extern "C" void foo(int c, char v);

...in which case, we're back to good old

_foo

...in the .obj symbol table.

My question is, is it possible to go the other way around? If I wanted to simulate C++ name mangling with a C function, this would be easy with gcc because gcc's name mangling rules only make use of identifier-friendly characters, thus the mangled name of foo becomes _ZN3fooEic, and we could easily write

void ZN3fooEic(int c, char v);

Back in Microsoft-compiler-land, I obviously can't create a function whose name is a completely invalid identifier called

void ?foo@@YAXHD@Z(int c, char v);

...but I'd still like that function to show up with that symbol name in the .obj symbol table.

Any ideas? I've looked through Visual C++'s supported pragmas, and I don't see anything useful.

like image 907
Ted Middleton Avatar asked Mar 07 '16 06:03

Ted Middleton


People also ask

How to get mangled name C++?

Well what you can do is compile your C++ program using g++ and get the .o file. Run the 'nm' command on the .o file thus obtained to get the mangled names! This method is viable on Linux systems.

Why does C++ mangle?

Since C++ supports function overloading, additional information has to be added to function names (called Name mangling) to avoid conflicts in binary code. 2. Function names may not be changed in C as it doesn't support function overloading. To avoid linking problems, C++ supports the extern “C” block.

What is symbol mangling?

Symbol mangling is done by C++ because the linker only supports a global namespace. Basically, mangling is a lot like what C programmer do by hand when they name their functions things like libfoo_getobjattr(). Except that the C++ mangling is done automatically, and so it has to really be unique.

What is mean by name mangling naming decoration?

In compiler construction, name mangling (also called name decoration) is a technique used to solve various problems caused by the need to resolve unique names for programming entities in many modern programming languages.


2 Answers

You can do this using __identifier:

#include <stdio.h>

#pragma warning(suppress: 4483)
extern "C" void __cdecl __identifier("?foo@@YAXHD@Z")(int c, char v)
{
    printf("%d %c\n", c, v);
}

void __cdecl foo(int, char);

int main()
{
    foo(10, 'x');
}
like image 199
James McNellis Avatar answered Oct 13 '22 00:10

James McNellis


You're right. That's not (directly) possible (note: never trust VSC++). However, there exists a nifty workaround if you really need this. First of all, in the C++ file...

extern "C" int proxy(int i, char c);

int foo(int i, char c)
{
    return proxy(i, c);
}

Then, in the C file...

int proxy(int i, char c)
{
    // Do whatever you wanna do here
}

Without having to type any mangled name at all, you are now able to call the foo function, which is actually just a wrapper around the C function proxy. This gives you the same effect as if proxy was actually foo, from C++'s point of view. The single penalty here is of course a quick 'n' dirty function call. If the ABI allows it, and the compiler is smart enough, this can be replaced with a single JMP x86 instruction.

Another way would be to write a function foo in C, and then use MinGW's objcopy in order to rename the symbol...

$ objcopy --redefine-sym "foo=?foo@@YAXHD@Z" foobar.obj

I'm not sure if that's possible just with VSC++ tools. It would be very unstable, unportable, and hacky anyways.

like image 25
3442 Avatar answered Oct 12 '22 23:10

3442