From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31453 invoked by alias); 27 Mar 2002 23:35:28 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 31444 invoked from network); 27 Mar 2002 23:35:27 -0000 Received: from unknown (HELO zwingli.cygnus.com) (208.245.165.35) by sources.redhat.com with SMTP; 27 Mar 2002 23:35:27 -0000 Received: by zwingli.cygnus.com (Postfix, from userid 442) id 1164E5EA11; Wed, 27 Mar 2002 18:35:25 -0500 (EST) From: Jim Blandy To: Chris Faylor Cc: gdb-patches@sources.redhat.com Subject: RFA: strip stdcall suffixes under Cygwin Message-Id: <20020327233525.1164E5EA11@zwingli.cygnus.com> Date: Wed, 27 Mar 2002 15:35:00 -0000 X-SW-Source: 2002-03/txt/msg00557.txt.bz2 Chris, I think I need your approval for this. 2002-03-27 Jim Blandy * config/i386/tm-cygwin.h: #define LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES. * symtab.c (LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES): Provide default #definition here, if tm-*.h file doesn't have one. (symbol_init_mangled_name): If the above is #defined, strip off the stdcall arg size, if present, from linker symbol names before trying to demangle them. Index: gdb/symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.59 diff -c -r1.59 symtab.c *** gdb/symtab.c 2002/03/27 23:10:23 1.59 --- gdb/symtab.c 2002/03/27 23:19:07 *************** *** 353,358 **** --- 353,362 ---- /* Initialize a symbol's mangled name. */ + #ifndef LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES + #define LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES (0) + #endif + /* Try to initialize the demangled name for a symbol, based on the language of that symbol. If the language is set to language_auto, it will attempt to find any demangling algorithm that works and *************** *** 369,381 **** char *mangled = gsymbol->name; char *demangled = NULL; if (gsymbol->language == language_unknown) gsymbol->language = language_auto; if (gsymbol->language == language_cplus || gsymbol->language == language_auto) { demangled = ! cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) { gsymbol->language = language_cplus; --- 373,418 ---- char *mangled = gsymbol->name; 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 (LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES) + { + 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; if (gsymbol->language == language_cplus || gsymbol->language == language_auto) { demangled = ! cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI); if (demangled != NULL) { gsymbol->language = language_cplus; *************** *** 391,397 **** if (gsymbol->language == language_java) { demangled = ! cplus_demangle (gsymbol->name, DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); if (demangled != NULL) { --- 428,434 ---- if (gsymbol->language == language_java) { demangled = ! cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_JAVA); if (demangled != NULL) { Index: gdb/symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.29 diff -c -r1.29 symtab.h *** gdb/symtab.h 2002/03/27 23:10:24 1.29 --- gdb/symtab.h 2002/03/27 23:19:08 *************** *** 159,170 **** } \ } while (0) #define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ (symbol_init_demangled_name (&symbol->ginfo, (obstack))) extern void symbol_init_demangled_name (struct general_symbol_info *symbol, struct obstack *obstack); - /* Macro that returns the demangled name for a symbol based on the language for that symbol. If no demangled name exists, returns NULL. */ --- 159,171 ---- } \ } while (0) + #define SYMBOL_INIT_DEMANGLED_NAME(symbol,obstack) \ (symbol_init_demangled_name (&symbol->ginfo, (obstack))) extern void symbol_init_demangled_name (struct general_symbol_info *symbol, struct obstack *obstack); + /* Macro that returns the demangled name for a symbol based on the language for that symbol. If no demangled name exists, returns NULL. */ Index: gdb/config/i386/tm-cygwin.h =================================================================== RCS file: /cvs/src/src/gdb/config/i386/tm-cygwin.h,v retrieving revision 1.11 diff -c -r1.11 tm-cygwin.h *** gdb/config/i386/tm-cygwin.h 2001/11/27 05:15:58 1.11 --- gdb/config/i386/tm-cygwin.h 2002/03/27 23:19:12 *************** *** 47,49 **** --- 47,51 ---- char *child_solib_loaded_library_pathname(int); void child_clear_solibs (void); void dll_symbol_command (char *, int); + + #define LINKER_SYMBOLS_HAVE_WIN32_STDCALL_ARG_SIZES (1)