plugin: more aggressive name change to avoid conflicts
[ia32rtools.git] / ida / saveasm / saveasm.cpp
index 51f67d2..46e2a2f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * ia32rtools
- * (C) notaz, 2013,2014
+ * (C) notaz, 2013-2015
  *
  * This work is licensed under the terms of 3-clause BSD license.
  * See COPYING file in the top-level directory.
@@ -82,6 +82,29 @@ static int is_name_reserved(const char *name)
   return 0;
 }
 
+/* these tend to cause linker conflicts */
+static const char *useless_names[] = {
+  "target", "addend", "lpMem", "Locale", "lpfn",
+  "CodePage", "uNumber", "Caption", "Default", "SubKey",
+  "ValueName", "OutputString", "LibFileName", "AppName",
+  "Buffer", "ClassName", "dwProcessId", "FileName",
+  "aExp", "aLog10", "aDelete", "aFont",
+  "lpCriticalSection", "CriticalSection", "lpAddress",
+  "lpBuffer", "lpClassName", "lpName",
+  "hHeap", "hEvent", "hHandle", "hObject",
+  "hLibModule", "hInstance",
+};
+
+static int is_name_useless(const char *name)
+{
+  int i;
+  for (i = 0; i < ARRAY_SIZE(useless_names); i++)
+    if (strcasecmp(name, useless_names[i]) == 0)
+      return 1;
+
+  return 0;
+}
+
 static int nonlocal_bt_cmp(const void *p1, const void *p2)
 {
   const ea_t *e1 = (const ea_t *)p1, *e2 = (const ea_t *)p2;
@@ -240,6 +263,7 @@ static void idaapi run(int /*arg*/)
   char buf[MAXSTR];
   char buf2[MAXSTR];
   const char *name;
+  const char *cp;
   struc_t *frame;
   func_t *func;
   ea_t ui_ea_block = 0, ea_size;
@@ -374,14 +398,18 @@ static void idaapi run(int /*arg*/)
 
           if (cmd.Operands[o].type == o_mem) {
             tmp_ea = cmd.Operands[o].addr;
-            flags_t tmp_ea_flags = get_flags_novalue(tmp_ea);
-            // ..but base float is ok..
-            int is_flt = isDwrd(tmp_ea_flags) || isFloat(tmp_ea_flags);
-            if (!is_flt && !isUnknown(tmp_ea_flags))
+            flags_t tmp_flg = get_flags_novalue(tmp_ea);
+            buf[0] = 0;
+            if (isDouble(tmp_flg))
+            {
+              get_name(ea, tmp_ea, buf, sizeof(buf));
+              msg("%x: converting dbl %x '%s'\n", ea, tmp_ea, buf);
+              doQwrd(tmp_ea, 8);
+            }
+            if (isOwrd(tmp_flg) || isYwrd(tmp_flg) || isTbyt(tmp_flg))
             {
-              buf[0] = 0;
               get_name(ea, tmp_ea, buf, sizeof(buf));
-              msg("%x: undefining %x '%s'\n", ea, tmp_ea, buf);
+              msg("%x: undefining lrg %x '%s'\n", ea, tmp_ea, buf);
               do_unknown(tmp_ea, DOUNK_EXPAND);
             }
           }
@@ -452,8 +480,12 @@ static void idaapi run(int /*arg*/)
       }
 
       // IDA vs masm float/mmx/xmm type incompatibility
-      if (isDouble(ea_flags) || isTbyt(ea_flags)
-       || isPackReal(ea_flags))
+      if (isDouble(ea_flags))
+      {
+        msg("%x: converting double\n", ea);
+        doQwrd(ea, 8);
+      }
+      else if (isTbyt(ea_flags) || isPackReal(ea_flags))
       {
         do_undef = 1;
       }
@@ -486,18 +518,42 @@ static void idaapi run(int /*arg*/)
   }
 
   // check namelist for reserved names and
-  // matching names with different case (nasm ignores case)
+  // matching names with different case (masm ignores case)
   n = get_nlist_size();
   for (i = 0; i < n; i++) {
+    int need_rename = 0;
+
     ea = get_nlist_ea(i);
+    ea_flags = get_flags_novalue(ea);
     name = get_nlist_name(i);
     if (name == NULL) {
       msg("%x: null name?\n", ea);
       continue;
     }
+
     qsnprintf(buf, sizeof(buf), "%s", name);
 
-    int need_rename = is_name_reserved(name);
+    // for short names, give them a postfix to solve link dupe problem
+    if (!isCode(ea_flags) && strlen(name) <= 4) {
+      qsnprintf(buf, sizeof(buf), "%s_%06X", name, ea);
+      need_rename = 1;
+    }
+    else {
+      qsnprintf(buf2, sizeof(buf2), "%s", name);
+      if ((p = strchr(buf2, '_')))
+        *p = 0;
+      if (is_name_useless(buf2)) {
+        msg("%x: removing name '%s'\n", ea, name);
+        ret = set_name(ea, "", SN_AUTO);
+        if (ret) {
+          n = get_nlist_size();
+          i--;
+          continue;
+        }
+      }
+    }
+
+    need_rename |= is_name_reserved(name);
     if (!need_rename) {
       p = buf;
       pp = (char **)bsearch(&p, name_cache, name_cache_size,
@@ -515,9 +571,20 @@ static void idaapi run(int /*arg*/)
 
     // rename vars with '?@' (funcs are ok)
     int change_qat = 0;
-    ea_flags = get_flags_novalue(ea);
-    if (!isCode(ea_flags) && strpbrk(name, "?@"))
-      change_qat = 1;
+    if (!isCode(ea_flags)) {
+      if (IS_START(name, "__imp_"))
+        need_rename = 0; /* some import */
+      else if (name[0] == '?' && strstr(name, "@@"))
+        need_rename = 0; /* c++ import */
+      else if (strchr(name, '?'))
+        change_qat = 1;
+      else if ((cp = strchr(name, '@'))) {
+        char *endp = NULL;
+        strtol(cp + 1, &endp, 10);
+        if (endp == NULL || *endp != 0)
+          change_qat = 1;
+      }
+    }
 
     if (need_rename || change_qat) {
       msg("%x: renaming name '%s'\n", ea, name);