do_child_store_inferior_registers (int r)
{
if (r >= 0)
- read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
+ deprecated_read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
else
{
for (r = 0; r < NUM_REGS; r++)
dll_name_ret,
MAX_PATH);
if (len == 0)
- error ("Error getting dll name: %u\n", GetLastError ());
+ error ("Error getting dll name: %u\n", (unsigned) GetLastError ());
if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
return 1;
{
struct so_stuff *next;
DWORD load_addr;
+ DWORD end_addr;
int loaded;
struct objfile *objfile;
char name[1];
char *p;
WIN32_FIND_DATA w32_fd;
HANDLE h = FindFirstFile(name, &w32_fd);
+ MEMORY_BASIC_INFORMATION m;
size_t len;
if (h == INVALID_HANDLE_VALUE)
so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
so->loaded = 0;
so->load_addr = load_addr;
+ if (!VirtualQueryEx (current_process_handle, (void *) load_addr, &m,
+ sizeof (m)))
+ so->end_addr = (DWORD) m.AllocationBase + m.RegionSize;
+ else
+ so->end_addr = load_addr + 0x2000; /* completely arbitrary */
+
so->next = NULL;
so->objfile = NULL;
strcpy (so->name, ppath);
return 0;
}
+char *
+solib_address (CORE_ADDR address)
+{
+ struct so_stuff *so;
+ for (so = &solib_start; so->next != NULL; so = so->next)
+ if (address >= so->load_addr && address <= so->end_addr)
+ return so->name;
+ return NULL;
+}
+
/* Return name of last loaded DLL. */
char *
child_solib_loaded_library_pathname (int pid)
memset (§ion_addrs, 0, sizeof (section_addrs));
section_addrs.other[0].name = ".text";
section_addrs.other[0].addr = load_addr;
- return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
+ return safe_symbol_file_add (name, from_tty, §ion_addrs, 0, OBJF_SHARED);
}
/* Load DLL symbol info. */
ourstatus->kind = TARGET_WAITKIND_LOADED;
ourstatus->value.integer = 0;
retval = main_thread_id;
+ re_enable_breakpoints_in_shlibs ();
break;
case UNLOAD_DLL_DEBUG_EVENT:
memset (¤t_event, 0, sizeof (current_event));
push_target (&child_ops);
child_init_thread_list ();
+ disable_breakpoints_in_shlibs (1);
child_clear_solibs ();
clear_proceed_status ();
init_wait_for_inferior ();
return 0;
}
+/* Try to set or remove a user privilege to the current process. Return -1
+ if that fails, the previous setting of that privilege otherwise.
+
+ This code is copied from the Cygwin source code and rearranged to allow
+ dynamically loading of the needed symbols from advapi32 which is only
+ available on NT/2K/XP. */
+static int
+set_process_privilege (const char *privilege, BOOL enable)
+{
+ static HMODULE advapi32 = NULL;
+ static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
+ static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
+ static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
+ DWORD, PTOKEN_PRIVILEGES, PDWORD);
+
+ HANDLE token_hdl = NULL;
+ LUID restore_priv;
+ TOKEN_PRIVILEGES new_priv, orig_priv;
+ int ret = -1;
+ DWORD size;
+
+ if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
+ return 0;
+
+ if (!advapi32)
+ {
+ if (!(advapi32 = LoadLibrary ("advapi32.dll")))
+ goto out;
+ if (!OpenProcessToken)
+ OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
+ if (!LookupPrivilegeValue)
+ LookupPrivilegeValue = GetProcAddress (advapi32,
+ "LookupPrivilegeValueA");
+ if (!AdjustTokenPrivileges)
+ AdjustTokenPrivileges = GetProcAddress (advapi32,
+ "AdjustTokenPrivileges");
+ if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
+ {
+ advapi32 = NULL;
+ goto out;
+ }
+ }
+
+ if (!OpenProcessToken (GetCurrentProcess (),
+ TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
+ &token_hdl))
+ goto out;
+
+ if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
+ goto out;
+
+ new_priv.PrivilegeCount = 1;
+ new_priv.Privileges[0].Luid = restore_priv;
+ new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
+
+ if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
+ sizeof orig_priv, &orig_priv, &size))
+ goto out;
+#if 0
+ /* Disabled, otherwise every `attach' in an unprivileged user session
+ would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
+ child_attach(). */
+ /* AdjustTokenPrivileges returns TRUE even if the privilege could not
+ be enabled. GetLastError () returns an correct error code, though. */
+ if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
+ goto out;
+#endif
+
+ ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
+
+out:
+ if (token_hdl)
+ CloseHandle (token_hdl);
+
+ return ret;
+}
+
/* Attach to process PID, then initialize for debugging it. */
static void
child_attach (char *args, int from_tty)
if (!args)
error_no_arg ("process-id to attach");
+ if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
+ {
+ printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
+ printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
+ }
+
pid = strtoul (args, 0, 0);
ok = DebugActiveProcess (pid);
+ saw_create = 0;
if (!ok)
error ("Can't attach to process.");
char *toexec;
char shell[MAX_PATH + 1]; /* Path to shell */
const char *sh;
+ int tty;
+ int ostdin, ostdout, ostderr;
if (!exec_file)
error ("No executable specified, use `target exec'.\n");
*temp = 0;
}
+ if (!inferior_io_terminal)
+ tty = ostdin = ostdout = ostderr = -1;
+ else
+ {
+ tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
+ if (tty < 0)
+ {
+ print_sys_errmsg (inferior_io_terminal, errno);
+ ostdin = ostdout = ostderr = -1;
+ }
+ else
+ {
+ ostdin = dup (0);
+ ostdout = dup (1);
+ ostderr = dup (2);
+ dup2 (tty, 0);
+ dup2 (tty, 1);
+ dup2 (tty, 2);
+ }
+ }
+
ret = CreateProcess (0,
args, /* command line */
NULL, /* Security */
NULL, /* current directory */
&si,
&pi);
+ if (tty >= 0)
+ {
+ close (tty);
+ dup2 (ostdin, 0);
+ dup2 (ostdout, 1);
+ dup2 (ostderr, 2);
+ close (ostdin);
+ close (ostdout);
+ close (ostderr);
+ }
+
if (!ret)
- error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
+ error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ());
CloseHandle (pi.hThread);
CloseHandle (pi.hProcess);
child_ops.to_terminal_save_ours = terminal_save_ours;
child_ops.to_terminal_info = child_terminal_info;
child_ops.to_kill = child_kill_inferior;
- child_ops.to_load = 0;
- child_ops.to_lookup_symbol = 0;
child_ops.to_create_inferior = child_create_inferior;
child_ops.to_mourn_inferior = child_mourn_inferior;
child_ops.to_can_run = child_can_run;
- child_ops.to_notice_signals = 0;
child_ops.to_thread_alive = win32_child_thread_alive;
child_ops.to_pid_to_str = cygwin_pid_to_str;
child_ops.to_stop = child_stop;
child_ops.to_stratum = process_stratum;
- child_ops.DONT_USE = 0;
child_ops.to_has_all_memory = 1;
child_ops.to_has_memory = 1;
child_ops.to_has_stack = 1;
child_ops.to_has_registers = 1;
child_ops.to_has_execution = 1;
- child_ops.to_sections = 0;
- child_ops.to_sections_end = 0;
child_ops.to_magic = OPS_MAGIC;
}