summaryrefslogtreecommitdiff
path: root/solenv/bin/remangle32to64.pl
diff options
context:
space:
mode:
Diffstat (limited to 'solenv/bin/remangle32to64.pl')
-rw-r--r--solenv/bin/remangle32to64.pl327
1 files changed, 327 insertions, 0 deletions
diff --git a/solenv/bin/remangle32to64.pl b/solenv/bin/remangle32to64.pl
new file mode 100644
index 000000000000..0ed98fbd4d4e
--- /dev/null
+++ b/solenv/bin/remangle32to64.pl
@@ -0,0 +1,327 @@
+#!/usr/bin/perl -w /* -*- indent-tabs-mode: nil -*- */
+
+# Version: MPL 1.1 / GPLv3+ / LGPLv3+
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Initial Developer of the Original Code is
+# Novell, Inc
+# Portions created by the Initial Developer are Copyright (C) 2011 Novell,
+# Inc. All Rights Reserved.
+#
+# Contributor(s): Tor Lillqvist <tml@iki.fi>
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+# the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+# in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+# instead of those above.
+
+# Change MSVC mangled C++ names from 32-bit form to the corresponding
+# 64-bit form. Each line of input can contain at most one mangled
+# name.
+
+# Based on experimentation with MSVC2008 and the following web pages:
+
+# http://www.geoffchappell.com/viewer.htm?doc=studies/msvc/language/decoration/index.htm
+# Thorough but incomplete. Still, describes details the below sources
+# don't mention.
+
+# http://cvs.winehq.com/cvsweb/wine/dlls/msvcrt/undname.c
+# Wine's __unDname function, presumably the most complete, although
+# not really written to act as "documentation"
+
+# http://mearie.org/documents/mscmangle/
+# Relatively complete but a bit badly structured and terse.
+
+# http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling
+# seems to be mostly a ripoff on the mearie.org page
+
+# Example transformation:
+# ??0ORealDynamicLoader@salhelper@@IAE@PAPAV01@ABVOUString@rtl@@1PAX2@Z =>
+# ??0ORealDynamicLoader@salhelper@@IEAA@PEAPEAV01@AEBVOUString@rtl@@1PEAX2@Z
+
+# It should be relatively easy to remove the modification parts of the
+# below code and use the regex for some other task on MSVC mangled
+# names.
+
+# The regular expression below accepts also nonsensical mangled names,
+# so it should not be used to verify correctness of mangled names.
+
+use strict;
+
+my @opstack = ();
+
+sub parse_number($)
+{
+ my ($num) = @_;
+
+ return $num + 1 if ($num eq '0' || ($num ge '1' && $num le '9'));
+
+ $num =~ tr/ABCDEFGHIJKLMNOP@/0123456789ABCDEF /;
+ hex($num);
+}
+
+sub format_number($)
+{
+ my ($num) = @_;
+
+ return $num - 1 if ($num <= 10);
+
+ $num = sprintf("%X", $num);
+ $num =~ tr/0123456789ABCDEF/ABCDEFGHIJKLMNOP/;
+ $num.'@';
+}
+
+sub double_thunk($$)
+{
+ my ($number, $position) = @_;
+
+ my $bytes = parse_number($number);
+ $bytes *= 2;
+ push(@opstack, 'r '.($position - length($number)).' '.length($number).' '.format_number($bytes));
+}
+
+while (<>)
+ {
+ m/
+ # Named subpattern definitions. I use names of the form
+ # __CamelCase__ for the named subpatters so that they are easier
+ # to see.
+ (?(DEFINE)
+ (?<__Number__>
+ \?? ([0-9] | [A-P]+@)
+ )
+ (?<__32BitChecksum__>
+ [A-P]{8}@
+ )
+ (?<__CallingConvention__>
+ (?:
+ [AB]
+ |
+ [C-L]
+ (?{ push(@opstack, 'r '.(pos()-1).' 1 A cdecl'); })
+ )
+ )
+ (?<__StringLiteralText__>
+ (?:
+ [_a-zA-Z0-9]
+ |
+ \?\$[A-P][A-P]
+ |
+ \?[0-9A-Za-z]
+ ){1,20}
+ )
+ (?<__Identifier__>
+ [_a-zA-Z\$][_a-zA-Z0-9\$]*@
+ )
+ (?<__ArgsZTerminated__>
+ (?&__DataTypeInArgs__)+ @? Z
+ )
+ (?<__ArgsNonZTerminated__>
+ (?&__DataTypeInArgs__)+ @?
+ )
+ (?<__TemplateName__>
+ (?&__Identifier__) (?&__ArgsNonZTerminated__)
+ )
+ (?<__Class__>
+ (?:
+ [0-9]
+ |
+ \?\$ (?&__TemplateName__)
+ |
+ (?&__Identifier__)
+ )+@
+ )
+ (?<__DataTypeCommon__>
+ (?:
+ # extended types like _int64, bool and wchar_t
+ _[D-NW]
+ |
+ # simple types
+ [C-KMNOXZ]
+ |
+ # class, struct, union, cointerface
+ [TUVY] (?&__Class__)
+ |
+ # references
+ [AB]
+ (?{ push(@opstack, 'i '.pos().' E reference'); })
+ (?&__ModifiedType__)
+ |
+ # pointers
+ [QRS]
+ (?{ push(@opstack, 'i '.pos().' E pointer'); })
+ (?&__ModifiedType__)
+ |
+ P
+ (?:
+ # function pointer
+ 6 (?&__CallingConvention__) (?&__DataTypeNotInArgs__) (?&__ArgsZTerminated__)
+ |
+ # other pointer
+ (?{ push(@opstack, 'i '.pos().' E pointer'); })
+ (?&__ModifiedType__)
+ )
+ |
+ W 4 (?&__Class__)
+ |
+ [0-9]
+ |
+ \$ (?:
+ [0DQ] (?&__Number__)
+ |
+ F (?&__Number__){2}
+ |
+ G (?&__Number__){3}
+ |
+ \$ [ABCD] (?&__DataTypeNotInArgs__)
+ )
+ )
+ )
+ (?<__ModifiedType__>
+ [ABCD]
+ (?:
+ # multidimensional array
+ Y (?&__Number__)+
+ )?
+ (?&__DataTypeNotInArgs__)
+ )
+ (?<__DataTypeInArgs__>
+ (?:
+ (?&__DataTypeCommon__)
+ |
+ # template parameter
+ \? (?&__Number__)
+ )
+ )
+ (?<__DataTypeNotInArgs__>
+ (?:
+ (?&__DataTypeCommon__)
+ |
+ \? (?&__ModifiedType__)
+ )
+ )
+ )
+
+ # All mangled names start with a question mark
+ \?
+ (?:
+ # Ctors, dtors, operators etc have separate a priori defined
+ # special mangled names like the very simple ?0 for constructor
+ # and ?_R16789 for "RTTI Base Class Descriptor at (6,7,8,9)"
+ # whatever that might mean.
+ (
+ \?
+ ([0-9A-Z]
+ |
+ _(?:
+ # C is for string literals, see below
+ # R is RTTI, see immediately below
+ [0-9ABD-QS-Z]
+ |
+ R0(?&__DataTypeNotInArgs__)
+ |
+ R1(?&__Number__){4}
+ |
+ R[234]
+ |
+ _(?:
+ E
+ )
+ )
+ )
+ )?
+ (?&__Class__)
+
+ (?:
+ # Static members and normal variables
+ [0-5]
+ (?&__DataTypeNotInArgs__)
+ [ABCD]
+ |
+ # Compiler-generated static
+ [67]
+ [ABCD]
+ (?:
+ @
+ |
+ (?&__Class__)
+ )
+ |
+ # Non-static Methods, implicit 'this'
+ [ABEFIJMNQRUV]
+ [AB]
+ (?{ push(@opstack, 'i '.(pos()-1).' E this'); })
+ (?&__CallingConvention__)
+ (?:
+ @
+ |
+ (?&__DataTypeNotInArgs__)
+ )
+ (?&__ArgsZTerminated__)
+ |
+ # Static methods
+ [CDKLST]
+ (?&__CallingConvention__)
+ (?:
+ @
+ |
+ (?&__DataTypeNotInArgs__)
+ )
+ (?&__ArgsZTerminated__)
+ |
+ # Thunks
+ [GHOPWX]
+ ((?&__Number__))
+ (?{ double_thunk($^N, pos()); })
+ [AB]
+ (?{ push(@opstack, 'i '.(pos()-1).' E this'); })
+ (?&__CallingConvention__)
+ (?:
+ @
+ |
+ (?&__DataTypeNotInArgs__)
+ )
+ (?&__ArgsZTerminated__)
+ |
+ # Functions
+ [YZ]
+ (?&__CallingConvention__)
+ (?:
+ @
+ |
+ (?&__DataTypeNotInArgs__)
+ )
+ (?&__ArgsZTerminated__)
+ |
+ # Template
+ \$ (?&__Identifier__) (?&__ArgsNonZTerminated__)
+ )
+ |
+ # pooled string literals
+ \?_C\@_[01](?&__Number__)(?&__32BitChecksum__)(?&__StringLiteralText__)@
+ )
+ /x;
+
+ while (my $op = pop(@opstack))
+ {
+ # print STDERR "op=$op\n";
+ my @a = split (' ', $op);
+ if ($a[0] eq 'i') {
+ substr($_,$a[1],0) = $a[2];
+ } elsif ($a[0] eq 'r') {
+ substr($_,$a[1],$a[2]) = $a[3];
+ }
+ }
+
+ print;
+ }