/*
* 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.
"type",
"offset",
"aam",
+ "aas",
"text",
"size",
"c",
"align",
+ "addr",
};
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;
}
static void do_def_line(char *buf, size_t buf_size, const char *line,
- ea_t ea)
+ ea_t ea, func_t *func)
{
+ char func_name[256] = "<nf>";
+ int is_libfunc = 0;
+ int global_label;
ea_t *ea_ret;
+ int i, len;
char *p;
- int len;
tag_remove(line, buf, buf_size); // remove color codes
len = strlen(buf);
if (*p == ':') {
ea_ret = (ea_t *)bsearch(&ea, nonlocal_bt, nonlocal_bt_cnt,
sizeof(nonlocal_bt[0]), nonlocal_bt_cmp);
- if (ea_ret != 0) {
+ global_label = (ea_ret != NULL);
+ if (!global_label) {
+ if (func != NULL) {
+ get_func_name(ea, func_name, sizeof(func_name));
+ is_libfunc = func->flags & FUNC_LIB;
+ }
+ for (i = 0; i < get_item_size(ea); i++) {
+ xrefblk_t xb;
+ if (xb.first_to(ea + i, XREF_DATA)) {
+ if (!is_libfunc && xb.type == dr_O)
+ msg("%x: offset xref in %s\n", ea, func_name);
+ global_label = 1;
+ }
+ }
+ }
+ if (global_label) {
if (p[1] != ' ')
msg("no trailing blank in '%s'\n", buf);
else
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;
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);
}
}
}
// 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;
}
do_undef = 1;
}
// masm doesn't understand large aligns
- else if (isAlign(ea_flags) && ea_size > 0x10) {
+ else if (isAlign(ea_flags) && ea_size >= 0x10)
+ {
msg("%x: undefining align %d\n", ea, ea_size);
do_unknown(ea, DOUNK_EXPAND);
}
}
}
- // check namelist for reserved names
+ // check namelist for reserved names and
+ // 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);
+
+ // 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,
+ sizeof(name_cache[0]), name_cache_cmp);
+ if (pp != NULL) {
+ if (pp > name_cache && stricmp(pp[-1], pp[0]) == 0)
+ need_rename = 1;
+ else if (pp < name_cache + name_cache_size - 1
+ && stricmp(pp[0], pp[1]) == 0)
+ {
+ need_rename = 1;
+ }
+ }
+ }
+
// 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 (change_qat || is_name_reserved(name)) {
+ if (need_rename || change_qat) {
msg("%x: renaming name '%s'\n", ea, name);
- qsnprintf(buf, sizeof(buf), "%s", name);
if (change_qat) {
for (p = buf; *p != 0; p++) {
ln.set_place(&pl);
n = ln.get_linecnt();
for (i = 0; i < n - 1; i++) {
- do_def_line(buf, sizeof(buf), ln.down(), ea);
+ do_def_line(buf, sizeof(buf), ln.down(), ea, NULL);
if (strstr(buf, "include"))
continue;
break;
}
+ func = get_func(ea);
+
segment_t *seg = getseg(ea);
if (!seg || (seg->type != SEG_CODE && seg->type != SEG_DATA))
goto pass;
pass:
n = ln.get_linecnt();
for (i = pl.lnnum; i < n; i++) {
- do_def_line(buf, sizeof(buf), ln.down(), ea);
+ do_def_line(buf, sizeof(buf), ln.down(), ea, func);
char *fw;
for (fw = buf; *fw != 0 && *fw == ' '; )