This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: strip stdcall suffixes under Cygwin



Chris, I think I need your approval for this.

2002-03-27  Jim Blandy  <jimb@redhat.com>

	* 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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]