summaryrefslogtreecommitdiffstats
path: root/7.8-symtab-cygwin.patch
diff options
context:
space:
mode:
Diffstat (limited to '7.8-symtab-cygwin.patch')
-rw-r--r--7.8-symtab-cygwin.patch44
1 files changed, 44 insertions, 0 deletions
diff --git a/7.8-symtab-cygwin.patch b/7.8-symtab-cygwin.patch
new file mode 100644
index 0000000..6af82ba
--- /dev/null
+++ b/7.8-symtab-cygwin.patch
@@ -0,0 +1,44 @@
+See https://sourceware.org/ml/gdb-patches/2002-03/msg00557.html
+
+--- origsrc/gdb-7.8/gdb/symtab.c 2014-07-29 14:37:42.000000000 +0200
++++ src/gdb-7.8/gdb/symtab.c 2014-08-04 12:04:47.173108524 +0200
+@@ -641,6 +641,39 @@ symbol_find_demangled_name (struct gener
+ {
+ char *demangled = NULL;
+
++ /* On Windows, some functions use the `stdcall' calling convention,
++ in which the callee is expected to pop the arguments off the
++ stack. Normally, the caller takes care of this, because only the
++ caller knows how many arguments it really passed. To avoid
++ confusion, the linker symbols for `stdcall' functions have names
++ with a suffix "@N" attached to them, where "N" is the number of
++ bytes they'll pop. That way, if a caller thinks some `stdcall'
++ function `foo' expects M argument bytes, but the definition of
++ `foo' expects N argument bytes, N != M, then the call will be a
++ reference to `foo@M', but the definition will have a linker
++ symbol `foo@N', and you'll get a link-time `symbol not found'
++ error, instead of a crash at run-time.
++
++ (Note how this fails to address calls through function pointers,
++ since the byte count isn't part of the function pointer's type.
++ Go, Microsoft!)
++
++ Whatever. But our demangler doesn't like that '@N' suffix, so we
++ need to strip it off. */
++ if (1)
++ {
++ char *arg_byte_suffix = strchr (mangled, '@');
++ if (arg_byte_suffix)
++ {
++ int prefix_len = arg_byte_suffix - mangled;
++ char *mangled_sans_suffix = alloca (prefix_len + 1);
++ memcpy (mangled_sans_suffix, mangled, prefix_len);
++ mangled_sans_suffix[prefix_len] = '\0';
++
++ mangled = mangled_sans_suffix;
++ }
++ }
++
+ if (gsymbol->language == language_unknown)
+ gsymbol->language = language_auto;
+