Share get_image_name between gdb and gdbserver
[deliverable/binutils-gdb.git] / gdb / nat / windows-nat.c
1 /* Internal interfaces for the Windows code
2 Copyright (C) 1995-2019 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18
19 #include "gdbsupport/common-defs.h"
20 #include "nat/windows-nat.h"
21
22 namespace windows_nat
23 {
24
25 windows_thread_info::~windows_thread_info ()
26 {
27 CloseHandle (h);
28 }
29
30 void
31 windows_thread_info::suspend ()
32 {
33 if (suspended != 0)
34 return;
35
36 if (SuspendThread (h) == (DWORD) -1)
37 {
38 DWORD err = GetLastError ();
39
40 /* We get Access Denied (5) when trying to suspend
41 threads that Windows started on behalf of the
42 debuggee, usually when those threads are just
43 about to exit.
44 We can get Invalid Handle (6) if the main thread
45 has exited. */
46 if (err != ERROR_INVALID_HANDLE && err != ERROR_ACCESS_DENIED)
47 warning (_("SuspendThread (tid=0x%x) failed. (winerr %u)"),
48 (unsigned) tid, (unsigned) err);
49 suspended = -1;
50 }
51 else
52 suspended = 1;
53 }
54
55 void
56 windows_thread_info::resume ()
57 {
58 if (suspended > 0)
59 {
60 stopped_at_software_breakpoint = false;
61
62 if (ResumeThread (h) == (DWORD) -1)
63 {
64 DWORD err = GetLastError ();
65 warning (_("warning: ResumeThread (tid=0x%x) failed. (winerr %u)"),
66 (unsigned) tid, (unsigned) err);
67 }
68 }
69 suspended = 0;
70 }
71
72 const char *
73 get_image_name (HANDLE h, void *address, int unicode)
74 {
75 #ifdef __CYGWIN__
76 static char buf[MAX_PATH];
77 #else
78 static char buf[(2 * MAX_PATH) + 1];
79 #endif
80 DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
81 char *address_ptr;
82 int len = 0;
83 char b[2];
84 SIZE_T done;
85
86 /* Attempt to read the name of the dll that was detected.
87 This is documented to work only when actively debugging
88 a program. It will not work for attached processes. */
89 if (address == NULL)
90 return NULL;
91
92 #ifdef _WIN32_WCE
93 /* Windows CE reports the address of the image name,
94 instead of an address of a pointer into the image name. */
95 address_ptr = address;
96 #else
97 /* See if we could read the address of a string, and that the
98 address isn't null. */
99 if (!ReadProcessMemory (h, address, &address_ptr,
100 sizeof (address_ptr), &done)
101 || done != sizeof (address_ptr)
102 || !address_ptr)
103 return NULL;
104 #endif
105
106 /* Find the length of the string. */
107 while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
108 && (b[0] != 0 || b[size - 1] != 0) && done == size)
109 continue;
110
111 if (!unicode)
112 ReadProcessMemory (h, address_ptr, buf, len, &done);
113 else
114 {
115 WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
116 ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
117 &done);
118 #ifdef __CYGWIN__
119 wcstombs (buf, unicode_address, MAX_PATH);
120 #else
121 WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
122 0, 0);
123 #endif
124 }
125
126 return buf;
127 }
128
129 }
This page took 0.042531 seconds and 4 git commands to generate.