[PATCH 23/26] [DbgHelp]: now moving the ELF loading code to unicode

Eric Pouech eric.pouech at wanadoo.fr
Wed Feb 21 14:56:27 CST 2007




A+
---

 dlls/dbghelp/dbghelp_private.h |    3 +
 dlls/dbghelp/elf_module.c      |  121 ++++++++++++++++++++++------------------
 dlls/dbghelp/module.c          |    5 +-
 3 files changed, 74 insertions(+), 55 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 816a540..a0bacde 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -432,6 +432,9 @@ extern DWORD WINAPI addr_to_linear(HANDL
 /* module.c */
 extern const WCHAR      S_ElfW[];
 extern const WCHAR      S_WineLoaderW[];
+extern const WCHAR      S_WinePThreadW[];
+extern const WCHAR      S_WineKThreadW[];
+extern const WCHAR      S_SlashW[];
 
 extern struct module*
                     module_find_by_addr(const struct process* pcs, unsigned long addr,
diff --git a/dlls/dbghelp/elf_module.c b/dlls/dbghelp/elf_module.c
index 2d7a8e0..6edc0fa 100644
--- a/dlls/dbghelp/elf_module.c
+++ b/dlls/dbghelp/elf_module.c
@@ -95,7 +95,7 @@ struct elf_info
     unsigned                    flags;          /* IN  one (or several) of the ELF_INFO constants */
     unsigned long               dbg_hdr_addr;   /* OUT address of debug header (if ELF_INFO_DEBUG_HEADER is set) */
     struct module*              module;         /* OUT loaded module (if ELF_INFO_MODULE is set) */
-    const char*                 module_name;    /* OUT found module name (if ELF_INFO_NAME is set) */
+    const WCHAR*                module_name;    /* OUT found module name (if ELF_INFO_NAME is set) */
 };
 
 /* structure holding information while handling an ELF image
@@ -1154,16 +1154,18 @@ BOOL elf_fetch_file_info(const WCHAR* na
  *	read or parsed)
  *	1 on success
  */
-static BOOL elf_load_file(struct process* pcs, const char* filename,
+static BOOL elf_load_file(struct process* pcs, const WCHAR* filename,
                           unsigned long load_offset, struct elf_info* elf_info)
 {
     BOOL                ret = FALSE;
     struct elf_file_map fmap;
     int	       	        i;
+    char                tmp[MAX_PATH];
 
-    TRACE("Processing elf file '%s' at %08lx\n", filename, load_offset);
+    TRACE("Processing elf file '%s' at %08lx\n", debugstr_w(filename), load_offset);
 
-    if (!elf_map_file(filename, &fmap)) goto leave;
+    WideCharToMultiByte(CP_UNIXCP, 0, filename, -1, tmp, sizeof(tmp), NULL, NULL);    
+    if (!elf_map_file(tmp, &fmap)) goto leave;
 
     /* Next, we need to find a few of the internal ELF headers within
      * this thing.  We need the main executable header, and the section
@@ -1171,11 +1173,11 @@ static BOOL elf_load_file(struct process
      */
     if (!fmap.elf_start && !load_offset)
         ERR("Relocatable ELF %s, but no load address. Loading at 0x0000000\n",
-            filename);
+            debugstr_w(filename));
     if (fmap.elf_start && load_offset)
     {
         WARN("Non-relocatable ELF %s, but load address of 0x%08lx supplied. "
-             "Assuming load address is corrupt\n", filename, load_offset);
+             "Assuming load address is corrupt\n", debugstr_w(filename), load_offset);
         load_offset = 0;
     }
 
@@ -1212,12 +1214,10 @@ static BOOL elf_load_file(struct process
 
     if (elf_info->flags & ELF_INFO_MODULE)
     {
-        WCHAR wfilename[MAX_PATH];
         struct elf_module_info *elf_module_info = 
             HeapAlloc(GetProcessHeap(), 0, sizeof(struct elf_module_info));
         if (!elf_module_info) goto leave;
-        MultiByteToWideChar(CP_UNIXCP, 0, filename, -1, wfilename, sizeof(wfilename) / sizeof(WCHAR));
-        elf_info->module = module_new(pcs, wfilename, DMT_ELF, FALSE,
+        elf_info->module = module_new(pcs, filename, DMT_ELF, FALSE,
                                       (load_offset) ? load_offset : fmap.elf_start, 
                                       fmap.elf_size, 0, calc_crc32(&fmap));
         if (!elf_info->module)
@@ -1241,8 +1241,14 @@ static BOOL elf_load_file(struct process
 
     if (elf_info->flags & ELF_INFO_NAME)
     {
-        elf_info->module_name = strcpy(HeapAlloc(GetProcessHeap(), 0,
-                                                 strlen(filename) + 1), filename);
+        WCHAR*  ptr;
+        ptr = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1) * sizeof(WCHAR));
+        if (ptr)
+        {
+            strcpyW(ptr, filename);
+            elf_info->module_name = ptr;
+        }
+        else ret = FALSE;
     }
 leave:
     elf_unmap_file(&fmap);
@@ -1255,34 +1261,39 @@ leave:
  * tries to load an ELF file from a set of paths (separated by ':')
  */
 static BOOL elf_load_file_from_path(HANDLE hProcess,
-                                    const char* filename,
+                                    const WCHAR* filename,
                                     unsigned long load_offset,
                                     const char* path,
                                     struct elf_info* elf_info)
 {
     BOOL                ret = FALSE;
-    char                *s, *t, *fn;
-    char*	        paths = NULL;
+    WCHAR               *s, *t, *fn;
+    WCHAR*	        pathW = NULL;
+    unsigned            len;
 
     if (!path) return FALSE;
 
-    paths = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
-    for (s = paths; s && *s; s = (t) ? (t+1) : NULL) 
+    len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
+    pathW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+    if (!pathW) return FALSE;
+    MultiByteToWideChar(CP_UNIXCP, 0, path, -1, pathW, len);
+
+    for (s = pathW; s && *s; s = (t) ? (t+1) : NULL) 
     {
-	t = strchr(s, ':');
+	t = strchrW(s, ':');
 	if (t) *t = '\0';
-	fn = HeapAlloc(GetProcessHeap(), 0, strlen(filename) + 1 + strlen(s) + 1);
+	fn = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(filename) + 1 + lstrlenW(s) + 1) * sizeof(WCHAR));
 	if (!fn) break;
-	strcpy(fn, s);
-	strcat(fn, "/");
-	strcat(fn, filename);
+	strcpyW(fn, s);
+	strcatW(fn, S_SlashW);
+	strcatW(fn, filename);
 	ret = elf_load_file(hProcess, fn, load_offset, elf_info);
 	HeapFree(GetProcessHeap(), 0, fn);
 	if (ret) break;
 	s = (t) ? (t+1) : NULL;
     }
     
-    HeapFree(GetProcessHeap(), 0, paths);
+    HeapFree(GetProcessHeap(), 0, pathW);
     return ret;
 }
 
@@ -1292,7 +1303,7 @@ static BOOL elf_load_file_from_path(HAND
  * Tries to load an ELF file from the dll path
  */
 static BOOL elf_load_file_from_dll_path(HANDLE hProcess,
-                                        const char* filename,
+                                        const WCHAR* filename,
                                         unsigned long load_offset,
                                         struct elf_info* elf_info)
 {
@@ -1302,11 +1313,18 @@ static BOOL elf_load_file_from_dll_path(
 
     while (!ret && (path = wine_dll_enum_load_path( index++ )))
     {
-        char *name = HeapAlloc( GetProcessHeap(), 0, strlen(path) + strlen(filename) + 2 );
+        WCHAR *name;
+        unsigned len;
+
+        len = MultiByteToWideChar(CP_UNIXCP, 0, path, -1, NULL, 0);
+
+        name = HeapAlloc( GetProcessHeap(), 0,
+                          (len + lstrlenW(filename) + 2) * sizeof(WCHAR) );
+
         if (!name) break;
-        strcpy( name, path );
-        strcat( name, "/" );
-        strcat( name, filename );
+        MultiByteToWideChar(CP_UNIXCP, 0, path, -1, name, len);
+        strcatW( name, S_SlashW );
+        strcatW( name, filename );
         ret = elf_load_file(hProcess, name, load_offset, elf_info);
         HeapFree( GetProcessHeap(), 0, name );
     }
@@ -1318,25 +1336,26 @@ static BOOL elf_load_file_from_dll_path(
  *
  * lookup a file in standard ELF locations, and if found, load it
  */
-static BOOL elf_search_and_load_file(struct process* pcs, const char* filename,
+static BOOL elf_search_and_load_file(struct process* pcs, const WCHAR* filename,
                                      unsigned long load_offset, 
                                      struct elf_info* elf_info)
 {
     BOOL                ret = FALSE;
     struct module*      module;
+    static WCHAR        S_libstdcPPW[] = {'l','i','b','s','t','d','c','+','+','\0'};
 
     if (filename == NULL || *filename == '\0') return FALSE;
-    if ((module = module_find_by_nameA(pcs, filename, DMT_ELF)))
+    if ((module = module_find_by_name(pcs, filename, DMT_ELF)))
     {
         elf_info->module = module;
         module->elf_info->elf_mark = 1;
         return module->module.SymType;
     }
 
-    if (strstr(filename, "libstdc++")) return FALSE; /* We know we can't do it */
+    if (strstrW(filename, S_libstdcPPW)) return FALSE; /* We know we can't do it */
     ret = elf_load_file(pcs, filename, load_offset, elf_info);
     /* if relative pathname, try some absolute base dirs */
-    if (!ret && !strchr(filename, '/'))
+    if (!ret && !strchrW(filename, '/'))
     {
         ret = elf_load_file_from_path(pcs, filename, load_offset, 
                                       getenv("PATH"), elf_info) ||
@@ -1354,7 +1373,7 @@ static BOOL elf_search_and_load_file(str
  * Enumerate ELF modules from a running process
  */
 static BOOL elf_enum_modules_internal(const struct process* pcs,
-                                      const char* main_name,
+                                      const WCHAR* main_name,
                                       elf_enum_modules_cb cb, void* user)
 {
     struct r_debug      dbg_hdr;
@@ -1383,8 +1402,8 @@ static BOOL elf_enum_modules_internal(co
 	    ReadProcessMemory(pcs->handle, lm.l_name, bufstr, sizeof(bufstr), NULL)) 
         {
 	    bufstr[sizeof(bufstr) - 1] = '\0';
-            if (main_name && !bufstr[0]) strcpy(bufstr, main_name);
             MultiByteToWideChar(CP_UNIXCP, 0, bufstr, -1, bufstrW, sizeof(bufstrW) / sizeof(WCHAR));
+            if (main_name && !bufstrW[0]) strcpyW(bufstrW, main_name);
             if (!cb(bufstrW, (unsigned long)lm.l_addr, user)) break;
 	}
     }
@@ -1400,10 +1419,8 @@ struct elf_sync
 static BOOL elf_enum_sync_cb(const WCHAR* name, unsigned long addr, void* user)
 {
     struct elf_sync*    es = user;
-    char                tmp[MAX_PATH];
     
-    WideCharToMultiByte(CP_UNIXCP, 0, name, -1, tmp, sizeof(tmp), 0, 0);
-    elf_search_and_load_file(es->pcs, tmp, addr, &es->elf_info);
+    elf_search_and_load_file(es->pcs, name, addr, &es->elf_info);
     return TRUE;
 }
     
@@ -1465,11 +1482,15 @@ static BOOL elf_search_loader(struct pro
      * or wine-kthread is not 100% safe
      */
     if ((ptr = getenv("WINELOADER")))
-        ret = elf_search_and_load_file(pcs, ptr, 0, elf_info);
+    {
+        WCHAR   tmp[MAX_PATH];
+        MultiByteToWideChar(CP_ACP, 0, ptr, -1, tmp, sizeof(tmp) / sizeof(WCHAR));
+        ret = elf_search_and_load_file(pcs, tmp, 0, elf_info);
+    }
     else 
     {
-        ret = elf_search_and_load_file(pcs, "wine-kthread", 0, elf_info) ||
-            elf_search_and_load_file(pcs, "wine-pthread", 0, elf_info);
+        ret = elf_search_and_load_file(pcs, S_WineKThreadW, 0, elf_info) ||
+            elf_search_and_load_file(pcs, S_WinePThreadW, 0, elf_info);
     }
     return ret;
 }
@@ -1517,7 +1538,7 @@ struct elf_load
 {
     struct process*     pcs;
     struct elf_info     elf_info;
-    char                name[MAX_PATH];
+    const WCHAR*        name;
     BOOL                ret;
 };
 
@@ -1527,20 +1548,17 @@ struct elf_load
  * Callback for elf_load_module, used to walk the list of loaded
  * modules.
  */
-static BOOL elf_load_cb(const WCHAR* nameW, unsigned long addr, void* user)
+static BOOL elf_load_cb(const WCHAR* name, unsigned long addr, void* user)
 {
     struct elf_load*    el = user;
-    const char*         p;
-    char                name[MAX_PATH];
-    
-    WideCharToMultiByte(CP_UNIXCP, 0, nameW, -1, name, sizeof(name), 0, 0);
+    const WCHAR*        p;
 
     /* memcmp is needed for matches when bufstr contains also version information
      * el->name: libc.so, name: libc.so.6.0
      */
-    p = strrchr(name, '/');
+    p = strrchrW(name, '/');
     if (!p++) p = name;
-    if (!memcmp(p, el->name, strlen(el->name)))
+    if (!memcmp(p, el->name, lstrlenW(el->name) * sizeof(WCHAR)))
     {
         el->ret = elf_search_and_load_file(el->pcs, name, addr, &el->elf_info);
         return FALSE;
@@ -1566,15 +1584,12 @@ struct module*  elf_load_module(struct p
 
     if (pcs->dbg_hdr_addr) /* we're debugging a life target */
     {
-        const WCHAR*  ptr;
-
         el.pcs = pcs;
         /* do only the lookup from the filename, not the path (as we lookup module
          * name in the process' loaded module list)
          */
-        ptr = strrchrW(name, '/');
-        if (!ptr++) ptr = name;
-        WideCharToMultiByte(CP_UNIXCP, 0, ptr, -1, el.name, sizeof(el.name), NULL, NULL);
+        el.name = strrchrW(name, '/');
+        if (!el.name++) el.name = name;
         el.ret = FALSE;
 
         if (!elf_enum_modules_internal(pcs, NULL, elf_load_cb, &el))
@@ -1582,7 +1597,7 @@ struct module*  elf_load_module(struct p
     }
     else if (addr)
     {
-        WideCharToMultiByte(CP_UNIXCP, 0, name, -1, el.name, sizeof(el.name), NULL, NULL);
+        el.name = name;
         el.ret = elf_search_and_load_file(pcs, el.name, addr, &el.elf_info);
     }
     if (!el.ret) return NULL;
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 6982359..007d211 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -37,8 +37,9 @@ const WCHAR        S_ElfW[]         = {'
 const WCHAR        S_WineLoaderW[]  = {'<','w','i','n','e','-','l','o','a','d','e','r','>','\0'};
 static const WCHAR S_DotSoW[]       = {'.','s','o','\0'};
 static const WCHAR S_DotPdbW[]      = {'.','p','d','b','\0'};
-static const WCHAR S_WinePThreadW[] = {'w','i','n','e','-','p','t','h','r','e','a','d','\0'};
-static const WCHAR S_WineKThreadW[] = {'w','i','n','e','-','k','t','h','r','e','a','d','\0'};
+const WCHAR        S_WinePThreadW[] = {'w','i','n','e','-','p','t','h','r','e','a','d','\0'};
+const WCHAR        S_WineKThreadW[] = {'w','i','n','e','-','k','t','h','r','e','a','d','\0'};
+const WCHAR        S_SlashW[]       = {'/','\0'};
 
 static const WCHAR S_AcmW[] = {'.','a','c','m','\0'};
 static const WCHAR S_DllW[] = {'.','d','l','l','\0'};



More information about the wine-patches mailing list