views:

297

answers:

4

Is it possible to unmangle names like these in Delphi? If so, where do I get more information?

Example of an error message where it cannot find a certain entry in the dbrtl100.bpl I want to know which exact function it cannot find (unit, class, name, parameters, etc).

---------------------------
myApp.exe - Entry Point Not Found
---------------------------
The procedure entry point @Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption could not be located in the dynamic link library dbrtl100.bpl. 
---------------------------
OK   
---------------------------

I know it is the method GetTableNameFromSQLEx in the Dbcommon unit (I have Delphi with the RTL/VCL sources), but sometimes I bump into apps where not all code is available for (yes, clients should always buy all the source code for 3rd party stuff, but sometimes they don't).

But say this is an example for which I do not have the code, or only the interface files (BDE.INT anyone?) What parameters does it have (i.e. which potential overload)? What return type does it have?

Is this mangling the same for any Delphi version?

--jeroen

Edit 1:

Thanks to Rob Kennedy: tdump -e dbrtl100.bpl does the trick. No need for -um at all:

C:\WINDOWS\system32>tdump -e dbrtl100.bpl | grep GetTableNameFromSQLEx
File STDIN:
00026050 1385 04AC __fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)

Edit 2:

Thanks to TOndrej who found this German EDN article (English Google Translation). That article describes the format pretty accurately, and it should be possible to create some Delphi code to unmangle this.

Pitty that the website the author mentions (and the email) are now dead, but good to know this info.

--jeroen

A: 

From the Delphi 2007 source files:

function GetTableNameFromSQLEx(const SQL: WideString; IdOption: IDENTIFIEROption): WideString;

This seems to be the same version, since I also have the same .BPL in my Windows\System32 folder.

Source can be found in [Program Files folders]\CodeGear\RAD Studio\5.0\source\Win32\db

Borland/Codegear/Embarcadero has used this encoding for a while now and never gave many details about the .BPL format. I've never been very interested in them since I hate using runtime libraries in my projects. I prefer to compile them into my projects, although this will result in much bigger executables.

Workshop Alex
Actually, I know which one it is: Delphi 2007 update 3, DBCommon.This was more meant for the BPLs for which you do not have sources, or need to hunt for the sources.I rephrased my question. Sorry for the inconvenience :-)
Jeroen Pluimers
+5  A: 

There is no function provided with Delphi that will unmangle function names, and I'm not aware of it being documented anywhere. Delphi in a Nutshell mentions that the "tdump" utility has a -um switch to make it unmangle symbols it finds. I've never tried it.

tdump -um -e dbrtl100.bpl

If that doesn't work, then it doesn't look like a very complicated scheme to unmangle yourself. Evidently, the name starts with "@" and is followed by the unit name and function name, separated by another "@" sign. That function name is followed by "$qqrx" and then the parameter types.

The parameter types are encoded using the character count of the type name followed by the same "@"-delimited format from before.

The "$" is necessary to mark the end of the function name and the start of the parameter types. The remaining mystery is the "qqrx" part. That's revealed by the article Tondrej found. The "qqr" indicates the calling convention, which in this case is register, a.k.a. fastcall. The "x" applies to the parameter and means that it's constant.

The return type doesn't need to be encoded in the mangled function name because overloading doesn't consider return types anyway.

Rob Kennedy
Thanks - this helps. Actually, the -um is not needed at all. This just works:C:\WINDOWS\system32>tdump -e dbrtl100.bpl | grep GetTableNameFromSQLExFile STDIN: 00026050 1385 04AC __fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)
Jeroen Pluimers
I think that's a recent enhancement, then. I'm pretty sure tdump hasn't always done that.
Rob Kennedy
+3  A: 

Also see this article (in German). I guess the mangling is probably backward-compatible, and new mangling schemes are introduced in later Delphi versions for new language features.

TOndrej
Thanks. I read German, so that is no problem. Now I want to accept two answers :-)
Jeroen Pluimers
+2  A: 

If you have C++Builder, check out $(BDS)\source\cpprtl\Source\misc\unmangle.c - it contains the source code for the unmangling mechanism used by TDUMP, the debugger and the linker. (C++Builder and Delphi use the same mangling scheme.)

Moritz Beutel
Briljant! Since when was that introduced? I seem only to have the 2009 and 2010 versions of them: D2009-Enterprise\source\cpprtl\Source\misc\unmangle.cD2010-Enterprise\source\cpprtl\Source\misc\unmangle.cGood reading material :-)
Jeroen Pluimers
I think this has been around as long as BCC itself. However the file was called um.c instead of unmangle.c in older versions.
Moritz Beutel