#define PE_DEF_FILE_ALIGNMENT          0x00000200
 #endif
 
+#define U(S) ${INITIAL_SYMBOL_CHAR} S
 
 static struct internal_extra_pe_aouthdr pe;
 static int dll;
       { "windows", 2, "WinMainCRTStartup" },
       { "console", 3, "mainCRTStartup" },
       { "posix",   7, "__PosixProcessStartup"},
-      { "wince",   9, "_WinMainCRTStartup" },
+      { "wince",   9, "WinMainCRTStartup" },
       { "xbox",   14, "mainCRTStartup" },
       { NULL, 0, NULL }
     };
 
              for (i = 0; i < nsyms; i++)
                {
-                 if (! CONST_STRNEQ (symbols[i]->name, "__head_"))
+                 if (! CONST_STRNEQ (symbols[i]->name, U ("_head_")))
                    continue;
 
                  if (pe_dll_extra_pe_debug)
                    printf ("->%s\n", symbols[i]->name);
 
                  pe_data_import_dll = (char*) (symbols[i]->name +
-                                               sizeof ("__head_") - 1);
+                                               sizeof (U ("_head_")) - 1);
                  break;
                }
 
            {
              struct bfd_link_hash_entry *h;
 
-             sprintf (buf, "_%s", pe_def_file->exports[i].internal_name);
+             sprintf (buf, "%s%s", U (""), pe_def_file->exports[i].internal_name);
 
              h = bfd_link_hash_lookup (link_info.hash, buf, TRUE, TRUE, TRUE);
              if (h == (struct bfd_link_hash_entry *) NULL)
 
     (so, DLL name is referenced by multiple entries), and pointer to symbol
     name thunk. Symbol name thunk is singleton vector (__nm_th_<symbol>)
     pointing to IMAGE_IMPORT_BY_NAME structure (__nm_<symbol>) directly
-    containing imported name. Here comes that "om the edge" problem mentioned
+    containing imported name. Here comes that "on the edge" problem mentioned
     above: PE specification rambles that name vector (OriginalFirstThunk)
     should run in parallel with addresses vector (FirstThunk), i.e. that they
     should have same number of elements and terminated with zero. We violate
 
 static autofilter_entry_type autofilter_symbolprefixlist[] =
 {
-  { STRING_COMMA_LEN ("__imp_") },
-  /* Do __imp_ explicitly to save time.  */
+  /* _imp_ is treated specially, as it is always underscored.  */
+  /* { STRING_COMMA_LEN ("_imp_") },  */
+  /* Don't export some c++ symbols.  */
   { STRING_COMMA_LEN ("__rtti_") },
+  { STRING_COMMA_LEN ("__builtin_") },
   /* Don't re-export auto-imported symbols.  */
   { STRING_COMMA_LEN ("_nm_") },
-  { STRING_COMMA_LEN ("__builtin_") },
   /* Don't export symbols specifying internal DLL layout.  */
   { STRING_COMMA_LEN ("_head_") },
   { STRING_COMMA_LEN (NULL) }
   free (local_copy);
 }
 
+static bfd_boolean
+is_import (const char* n)
+{
+       return (CONST_STRNEQ (n, "__imp_"));
+}
 
 /* abfd is a bfd containing n (or NULL)
    It can be used for contextual checks.  */
   if (abfd && abfd->my_archive)
     libname = lbasename (abfd->my_archive->filename);
 
-  /* We should not re-export imported stuff.  */
-  if (CONST_STRNEQ (n, "_imp_"))
-    return 0;
-
   for (i = 0; i < d->num_exports; i++)
     if (strcmp (d->exports[i].name, n) == 0)
       return 0;
 
                  /* We should not re-export imported stuff.  */
                  {
-                   char *name = xmalloc (strlen (sn) + 2 + 6);
-                   sprintf (name, "%s%s", U("_imp_"), sn);
+                   if (is_import (sn))
+                         continue;
+
+                   char *name = xmalloc (strlen ("__imp_") + strlen (sn) + 1);
+                   sprintf (name, "%s%s", "__imp_", sn);
 
                    blhe = bfd_link_hash_lookup (info->hash, name,
                                                 FALSE, FALSE, FALSE);
                      continue;
                  }
 
-                 if (*sn == '_')
+                 if (pe_details->underscored && *sn == '_')
                    sn++;
 
                  if (auto_export (b, pe_def_file, sn))
     {
       for (i = 0; i < NE; i++)
        {
+         if (is_import (pe_def_file->exports[i].name))
+           continue;
+
          if (strchr (pe_def_file->exports[i].name, '@'))
            {
              int lead_at = (*pe_def_file->exports[i].name == '@');
                    BSF_GLOBAL, 0);
       if (! exp->flag_data)
        quick_symbol (abfd, "", exp->internal_name, "", tx, BSF_GLOBAL, 0);
-      quick_symbol (abfd, U ("_imp_"), exp->internal_name, "", id5,
+      quick_symbol (abfd, "__imp_", exp->internal_name, "", id5,
                    BSF_GLOBAL, 0);
       /* Fastcall applies only to functions,
         so no need for auto-import symbol.  */
       if (! exp->flag_data)
        quick_symbol (abfd, U (""), exp->internal_name, "", tx,
                      BSF_GLOBAL, 0);
-      quick_symbol (abfd, U ("_imp__"), exp->internal_name, "", id5,
+      quick_symbol (abfd, "__imp_", U (""), exp->internal_name, id5,
                    BSF_GLOBAL, 0);
       /* Symbol to reference ord/name of imported
         data symbol, used to implement auto-import.  */
       if (exp->flag_data)
-       quick_symbol (abfd, U("_nm__"), exp->internal_name, "", id6,
+       quick_symbol (abfd, U ("_nm_"), U (""), exp->internal_name, id6,
                      BSF_GLOBAL,0);
     }
   if (pe_dll_compat_implib)
   symtab = xmalloc (2 * sizeof (asymbol *));
   extern_rt_rel = quick_section (abfd, ".rdata", SEC_HAS_CONTENTS, 2);
 
-  quick_symbol (abfd, "", "__pei386_runtime_relocator", "", UNDSEC,
+  quick_symbol (abfd, "", U ("_pei386_runtime_relocator"), "", UNDSEC,
                BSF_NO_FLAGS, 0);
 
   bfd_set_section_size (abfd, extern_rt_rel, 4);
            char *name = xmalloc (len + 2 + 6);
 
            if (lead_at)
-             sprintf (name, "%s%s", "",
+             sprintf (name, "%s",
                       pe_def_file->imports[i].internal_name);
            else
              sprintf (name, "%s%s",U (""),
            if (!blhe || (blhe && blhe->type != bfd_link_hash_undefined))
              {
                if (lead_at)
-                 sprintf (name, "%s%s", U ("_imp_"),
+                 sprintf (name, "%s%s", "__imp_", 
                           pe_def_file->imports[i].internal_name);
                else
-                 sprintf (name, "%s%s", U ("_imp__"),
+                 sprintf (name, "%s%s%s", "__imp_", U (""),
                           pe_def_file->imports[i].internal_name);
 
                blhe = bfd_link_hash_lookup (link_info->hash, name,