diff options
Diffstat (limited to 'gdb/windows-nat.c')
-rw-r--r-- | gdb/windows-nat.c | 669 |
1 files changed, 194 insertions, 475 deletions
diff --git a/gdb/windows-nat.c b/gdb/windows-nat.c index d952572..9abe333 100644 --- a/gdb/windows-nat.c +++ b/gdb/windows-nat.c @@ -53,10 +53,14 @@ #include <sys/param.h> #include <unistd.h> #include "exec.h" +#include "solist.h" #include "i386-tdep.h" #include "i387-tdep.h" +static struct target_ops win32_ops; +static struct target_so_ops win32_so_ops; + /* If we're not using the old Cygwin header file set, define the following which never should have been in the generic Win32 API headers in the first place since they were our own invention... */ @@ -87,9 +91,9 @@ static int debug_registers_used; #define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x #define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x -static void child_stop (void); -static int win32_child_thread_alive (ptid_t); -void child_kill_inferior (void); +static void win32_stop (void); +static int win32_win32_thread_alive (ptid_t); +static void win32_kill_inferior (void); static enum target_signal last_sig = TARGET_SIGNAL_0; /* Set if a signal was received from the debugged process */ @@ -251,7 +255,7 @@ thread_rec (DWORD id, int get_context) /* Add a thread to the thread list */ static thread_info * -child_add_thread (DWORD id, HANDLE h) +win32_add_thread (DWORD id, HANDLE h) { thread_info *th; @@ -287,11 +291,11 @@ child_add_thread (DWORD id, HANDLE h) /* Clear out any old thread list and reintialize it to a pristine state. */ static void -child_init_thread_list (void) +win32_init_thread_list (void) { thread_info *th = &thread_head; - DEBUG_EVENTS (("gdb: child_init_thread_list\n")); + DEBUG_EVENTS (("gdb: win32_init_thread_list\n")); init_thread_list (); while (th->next != NULL) { @@ -305,7 +309,7 @@ child_init_thread_list (void) /* Delete a thread from the list of threads */ static void -child_delete_thread (DWORD id) +win32_delete_thread (DWORD id) { thread_info *th; @@ -328,7 +332,7 @@ child_delete_thread (DWORD id) } static void -do_child_fetch_inferior_registers (int r) +do_win32_fetch_inferior_registers (int r) { char *context_offset = ((char *) ¤t_thread->context) + mappings[r]; long l; @@ -369,24 +373,24 @@ do_child_fetch_inferior_registers (int r) else { for (r = 0; r < NUM_REGS; r++) - do_child_fetch_inferior_registers (r); + do_win32_fetch_inferior_registers (r); } #undef I387_ST0_REGNUM } static void -child_fetch_inferior_registers (int r) +win32_fetch_inferior_registers (int r) { current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); /* Check if current_thread exists. Windows sometimes uses a non-existent thread id in its events */ if (current_thread) - do_child_fetch_inferior_registers (r); + do_win32_fetch_inferior_registers (r); } static void -do_child_store_inferior_registers (int r) +do_win32_store_inferior_registers (int r) { if (!current_thread) /* Windows sometimes uses a non-existent thread id in its events */; @@ -396,19 +400,19 @@ do_child_store_inferior_registers (int r) else { for (r = 0; r < NUM_REGS; r++) - do_child_store_inferior_registers (r); + do_win32_store_inferior_registers (r); } } /* Store a new register value into the current thread context */ static void -child_store_inferior_registers (int r) +win32_store_inferior_registers (int r) { current_thread = thread_rec (PIDGET (inferior_ptid), TRUE); /* Check if current_thread exists. Windows sometimes uses a non-existent thread id in its events */ if (current_thread) - do_child_store_inferior_registers (r); + do_win32_store_inferior_registers (r); } static int psapi_loaded = 0; @@ -417,7 +421,7 @@ static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWOR static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL; static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL; -int +static int psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret) { DWORD len; @@ -509,28 +513,24 @@ struct safe_symbol_file_add_args struct objfile *ret; }; +/*CGF*/ /* Maintain a linked list of "so" information. */ -struct so_stuff +struct lm_info { - struct so_stuff *next; DWORD load_addr; DWORD end_addr; - int loaded; - struct objfile *objfile; - char name[1]; -} solib_start, *solib_end; +}; + +static struct so_list solib_start, *solib_end; /* Call symbol_file_add with stderr redirected. We don't care if there are errors. */ static int safe_symbol_file_add_stub (void *argv) { -#define p ((struct safe_symbol_file_add_args *)argv) - struct so_stuff *so = &solib_start; +#define p ((struct safe_symbol_file_add_args *) argv) + struct so_list *so = &solib_start; - while ((so = so->next)) - if (so->loaded && strcasecmp (so->name, p->name) == 0) - return 0; p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags); return !!p->ret; #undef p @@ -579,12 +579,12 @@ safe_symbol_file_add (char *name, int from_tty, } /* Remember the maximum DLL length for printing in info dll command. */ -int max_dll_name_len; +static int max_dll_name_len; static void register_loaded_dll (const char *name, DWORD load_addr) { - struct so_stuff *so; + struct so_list *so; char ppath[MAX_PATH + 1]; char buf[MAX_PATH + 1]; char cwd[MAX_PATH + 1]; @@ -611,19 +611,24 @@ register_loaded_dll (const char *name, DWORD load_addr) } } + if (strcasecmp (buf, "ntdll.dll") == 0) + { + GetSystemDirectory (buf, sizeof (buf)); + strcat (buf, "\\ntdll.dll"); + } cygwin_conv_to_posix_path (buf, ppath); - so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1); - so->loaded = 0; - so->load_addr = load_addr; + so = (struct so_list *) xmalloc (sizeof (struct so_list) + strlen (ppath) + 8 + 1); + memset (so, 0, sizeof (*so)); + so->lm_info = (struct lm_info *) xmalloc (sizeof (struct lm_info)); + so->lm_info->load_addr = load_addr; if (VirtualQueryEx (current_process_handle, (void *) load_addr, &m, sizeof (m))) - so->end_addr = (DWORD) m.AllocationBase + m.RegionSize; + so->lm_info->end_addr = (DWORD) m.AllocationBase + m.RegionSize; else - so->end_addr = load_addr + 0x2000; /* completely arbitrary */ + so->lm_info->end_addr = load_addr + 0x2000; /* completely arbitrary */ so->next = NULL; - so->objfile = NULL; - strcpy (so->name, ppath); + strcpy (so->so_name, ppath); solib_end->next = so; solib_end = so; @@ -632,7 +637,7 @@ register_loaded_dll (const char *name, DWORD load_addr) max_dll_name_len = len; } -char * +static char * get_image_name (HANDLE h, void *address, int unicode) { static char buf[(2 * MAX_PATH) + 1]; @@ -700,22 +705,43 @@ handle_load_dll (void *dummy) return 1; } +static void +win32_free_so (struct so_list *so) +{ + if (so->objfile) + free_objfile (so->objfile); + if (so->lm_info) + xfree (so->lm_info); +} + +static struct so_list * +win32_current_sos (void) +{ + return solib_start.next; +} + +static void +win32_relocate_section_addresses (struct so_list *so, + struct section_table *sec) +{ + /* FIXME */ + return; +} + static int handle_unload_dll (void *dummy) { DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000; - struct so_stuff *so; + struct so_list *so; for (so = &solib_start; so->next != NULL; so = so->next) - if (so->next->load_addr == lpBaseOfDll) + if (so->next->lm_info->load_addr == lpBaseOfDll) { - struct so_stuff *sodel = so->next; + struct so_list *sodel = so->next; so->next = sodel->next; if (!so->next) solib_end = so; - if (sodel->objfile) - free_objfile (sodel->objfile); - xfree(sodel); + free_so (sodel); return 1; } error (_("Error: dll starting at 0x%lx not found."), (DWORD) lpBaseOfDll); @@ -723,149 +749,17 @@ handle_unload_dll (void *dummy) 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) -{ - return !solib_end || !solib_end->name[0] ? NULL : solib_end->name; -} - /* Clear list of loaded DLLs. */ -void -child_clear_solibs (void) +static void +win32_clear_solib (void) { - struct so_stuff *so, *so1 = solib_start.next; - - while ((so = so1) != NULL) - { - so1 = so->next; - xfree (so); - } + struct so_list *so, *so1 = solib_start.next; solib_start.next = NULL; - solib_start.objfile = NULL; solib_end = &solib_start; max_dll_name_len = sizeof ("DLL Name") - 1; } -/* Get the loaded address of all sections, given that .text was loaded - at text_load. Assumes that all sections are subject to the same - relocation offset. Returns NULL if problems occur or if the - sections were not relocated. */ - -static struct section_addr_info * -get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load) -{ - struct section_addr_info *result = NULL; - int section_count = bfd_count_sections (abfd); - asection *text_section = bfd_get_section_by_name (abfd, ".text"); - CORE_ADDR text_vma; - - if (!text_section) - { - /* Couldn't get the .text section. Weird. */ - } - - else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section))) - { - /* DLL wasn't relocated. */ - } - - else - { - /* Figure out all sections' loaded addresses. The offset here is - such that taking a bfd_get_section_vma() result and adding - offset will give the real load address of the section. */ - - CORE_ADDR offset = text_load - text_vma; - - struct section_table *table_start = NULL; - struct section_table *table_end = NULL; - struct section_table *iter = NULL; - - build_section_table (abfd, &table_start, &table_end); - - for (iter = table_start; iter < table_end; ++iter) - { - /* Relocated addresses. */ - iter->addr += offset; - iter->endaddr += offset; - } - - result = build_section_addr_info_from_section_table (table_start, - table_end); - - xfree (table_start); - } - - return result; -} - -/* Add DLL symbol information. */ -static struct objfile * -solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr) -{ - struct section_addr_info *addrs = NULL; - static struct objfile *result = NULL; - bfd *abfd = NULL; - - /* The symbols in a dll are offset by 0x1000, which is the - the offset from 0 of the first byte in an image - because - of the file header and the section alignment. */ - - if (!name || !name[0]) - return NULL; - - abfd = bfd_openr (name, "pei-i386"); - - if (!abfd) - { - /* pei failed - try pe */ - abfd = bfd_openr (name, "pe-i386"); - } - - if (abfd) - { - if (bfd_check_format (abfd, bfd_object)) - { - addrs = get_relocated_section_addrs (abfd, load_addr); - } - - bfd_close (abfd); - } - - if (addrs) - { - result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED); - free_section_addr_info (addrs); - } - else - { - /* Fallback on handling just the .text section. */ - struct cleanup *my_cleanups; - - addrs = alloc_section_addr_info (1); - my_cleanups = make_cleanup (xfree, addrs); - addrs->other[0].name = ".text"; - addrs->other[0].addr = load_addr; - - result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED); - do_cleanups (my_cleanups); - } - - return result; -} - /* Load DLL symbol info. */ void dll_symbol_command (char *args, int from_tty) @@ -889,17 +783,17 @@ dll_symbol_command (char *args, int from_tty) } /* List currently loaded DLLs. */ -void +static void info_dll_command (char *ignore, int from_tty) { - struct so_stuff *so = &solib_start; + struct so_list *so = &solib_start; if (!so->next) return; printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name"); while ((so = so->next) != NULL) - printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr); + printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->so_name, so->lm_info->load_addr); return; } @@ -1175,7 +1069,7 @@ handle_exception (struct target_waitstatus *ourstatus) /* Resume all artificially suspended threads if we are continuing execution */ static BOOL -child_continue (DWORD continue_status, int id) +win32_continue (DWORD continue_status, int id) { int i; thread_info *th; @@ -1219,13 +1113,13 @@ child_continue (DWORD continue_status, int id) /* Called in pathological case where Windows fails to send a CREATE_PROCESS_DEBUG_EVENT after an attach. */ -DWORD +static DWORD fake_create_process (void) { current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE, current_event.dwProcessId); main_thread_id = current_event.dwThreadId; - current_thread = child_add_thread (main_thread_id, + current_thread = win32_add_thread (main_thread_id, current_event.u.CreateThread.hThread); return main_thread_id; } @@ -1234,7 +1128,7 @@ fake_create_process (void) handling by WFI (or whatever). */ static int -get_child_debug_event (int pid, struct target_waitstatus *ourstatus) +get_win32_debug_event (int pid, struct target_waitstatus *ourstatus) { BOOL debug_event; DWORD continue_status, event_code; @@ -1274,7 +1168,7 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus) break; } /* Record the existence of this thread */ - th = child_add_thread (current_event.dwThreadId, + th = win32_add_thread (current_event.dwThreadId, current_event.u.CreateThread.hThread); if (info_verbose) printf_unfiltered ("[New %s]\n", @@ -1290,7 +1184,7 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus) "EXIT_THREAD_DEBUG_EVENT")); if (current_event.dwThreadId != main_thread_id) { - child_delete_thread (current_event.dwThreadId); + win32_delete_thread (current_event.dwThreadId); th = &dummy_thread_info; } break; @@ -1309,10 +1203,10 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus) current_process_handle = current_event.u.CreateProcessInfo.hProcess; if (main_thread_id) - child_delete_thread (main_thread_id); + win32_delete_thread (main_thread_id); main_thread_id = current_event.dwThreadId; /* Add the main thread */ - th = child_add_thread (main_thread_id, + th = win32_add_thread (main_thread_id, current_event.u.CreateProcessInfo.hThread); retval = ourstatus->value.related_pid = current_event.dwThreadId; break; @@ -1395,7 +1289,7 @@ get_child_debug_event (int pid, struct target_waitstatus *ourstatus) } if (!retval || saw_create != 1) - CHECK (child_continue (continue_status, -1)); + CHECK (win32_continue (continue_status, -1)); else { inferior_ptid = pid_to_ptid (retval); @@ -1408,7 +1302,7 @@ out: /* Wait for interesting events to occur in the target process. */ static ptid_t -child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) +win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus) { int pid = PIDGET (ptid); @@ -1420,7 +1314,7 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) while (1) { - int retval = get_child_debug_event (pid, ourstatus); + int retval = get_win32_debug_event (pid, ourstatus); if (retval) return pid_to_ptid (retval); else @@ -1431,13 +1325,13 @@ child_wait (ptid_t ptid, struct target_waitstatus *ourstatus) detach = deprecated_ui_loop_hook (0); if (detach) - child_kill_inferior (); + win32_kill_inferior (); } } } static void -do_initial_child_stuff (DWORD pid) +do_initial_win32_stuff (DWORD pid) { extern int stop_after_trap; int i; @@ -1451,9 +1345,9 @@ do_initial_child_stuff (DWORD pid) dr[i] = 0; current_event.dwProcessId = pid; memset (¤t_event, 0, sizeof (current_event)); - push_target (&deprecated_child_ops); + push_target (&win32_ops); disable_breakpoints_in_shlibs (1); - child_clear_solibs (); + win32_clear_solib (); clear_proceed_status (); init_wait_for_inferior (); @@ -1563,7 +1457,7 @@ set_process_privilege (const char *privilege, BOOL enable) #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(). */ + win32_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) @@ -1581,7 +1475,7 @@ out: /* Attach to process PID, then initialize for debugging it. */ static void -child_attach (char *args, int from_tty) +win32_attach (char *args, int from_tty) { BOOL ok; DWORD pid; @@ -1597,7 +1491,7 @@ child_attach (char *args, int from_tty) pid = strtoul (args, 0, 0); /* Windows pid */ - child_init_thread_list (); + win32_init_thread_list (); ok = DebugActiveProcess (pid); saw_create = 0; @@ -1632,19 +1526,19 @@ child_attach (char *args, int from_tty) gdb_flush (gdb_stdout); } - do_initial_child_stuff (pid); + do_initial_win32_stuff (pid); target_terminal_ours (); } static void -child_detach (char *args, int from_tty) +win32_detach (char *args, int from_tty) { int detached = 1; if (has_detach_ability ()) { delete_command (NULL, 0); - child_continue (DBG_CONTINUE, -1); + win32_continue (DBG_CONTINUE, -1); if (!DebugActiveProcessStop (current_event.dwProcessId)) { error (_("Can't detach process %lu (error %lu)"), @@ -1663,11 +1557,11 @@ child_detach (char *args, int from_tty) gdb_flush (gdb_stdout); } inferior_ptid = null_ptid; - unpush_target (&deprecated_child_ops); + unpush_target (&win32_ops); } -char * -child_pid_to_exec_file (int pid) +static char * +win32_pid_to_exec_file (int pid) { /* Try to find the process path using the Cygwin internal process list pid isn't a valid pid, unfortunately. Use current_event.dwProcessId @@ -1699,14 +1593,14 @@ child_pid_to_exec_file (int pid) /* Print status information about what we're accessing. */ static void -child_files_info (struct target_ops *ignore) +win32_files_info (struct target_ops *ignore) { printf_unfiltered ("\tUsing the running image of %s %s.\n", attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid)); } static void -child_open (char *arg, int from_tty) +win32_open (char *arg, int from_tty) { error (_("Use the \"run\" command to start a Unix child process.")); } @@ -1717,7 +1611,7 @@ child_open (char *arg, int from_tty) ENV is the environment vector to pass. Errors reported with error(). */ static void -child_create_inferior (char *exec_file, char *allargs, char **env, +win32_create_inferior (char *exec_file, char *allargs, char **env, int from_tty) { char *winenv; @@ -1871,7 +1765,7 @@ child_create_inferior (char *exec_file, char *allargs, char **env, } } - child_init_thread_list (); + win32_init_thread_list (); ret = CreateProcess (0, args, /* command line */ NULL, /* Security */ @@ -1905,18 +1799,18 @@ child_create_inferior (char *exec_file, char *allargs, char **env, else saw_create = 0; - do_initial_child_stuff (pi.dwProcessId); + do_initial_win32_stuff (pi.dwProcessId); - /* child_continue (DBG_CONTINUE, -1); */ + /* win32_continue (DBG_CONTINUE, -1); */ proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0); } static void -child_mourn_inferior (void) +win32_mourn_inferior (void) { - (void) child_continue (DBG_CONTINUE, -1); + (void) win32_continue (DBG_CONTINUE, -1); i386_cleanup_dregs(); - unpush_target (&deprecated_child_ops); + unpush_target (&win32_ops); generic_mourn_inferior (); } @@ -1924,15 +1818,15 @@ child_mourn_inferior (void) ^C on the controlling terminal. */ static void -child_stop (void) +win32_stop (void) { DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n")); CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId)); registers_changed (); /* refresh register state */ } -int -child_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len, +static int +win32_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len, int write, struct mem_attrib *mem, struct target_ops *target) { @@ -1957,14 +1851,14 @@ child_xfer_memory (CORE_ADDR memaddr, gdb_byte *our, int len, return done; } -void -child_kill_inferior (void) +static void +win32_kill_inferior (void) { CHECK (TerminateProcess (current_process_handle, 0)); for (;;) { - if (!child_continue (DBG_CONTINUE, -1)) + if (!win32_continue (DBG_CONTINUE, -1)) break; if (!WaitForDebugEvent (¤t_event, INFINITE)) break; @@ -1977,11 +1871,11 @@ child_kill_inferior (void) /* this may fail in an attached process so don't check. */ if (current_thread && current_thread->h) (void) CloseHandle (current_thread->h); - target_mourn_inferior (); /* or just child_mourn_inferior? */ + target_mourn_inferior (); /* or just win32_mourn_inferior? */ } -void -child_resume (ptid_t ptid, int step, enum target_signal sig) +static void +win32_resume (ptid_t ptid, int step, enum target_signal sig) { thread_info *th; DWORD continue_status = DBG_CONTINUE; @@ -2024,7 +1918,7 @@ child_resume (ptid_t ptid, int step, enum target_signal sig) last_sig = TARGET_SIGNAL_0; - DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n", + DEBUG_EXEC (("gdb: win32_resume (pid=%d, step=%d, sig=%d);\n", pid, step, sig)); /* Get context for currently selected thread */ @@ -2034,7 +1928,7 @@ child_resume (ptid_t ptid, int step, enum target_signal sig) if (step) { /* Single step by setting t bit */ - child_fetch_inferior_registers (PS_REGNUM); + win32_fetch_inferior_registers (PS_REGNUM); th->context.EFlags |= FLAG_TRACE_BIT; } @@ -2058,68 +1952,94 @@ child_resume (ptid_t ptid, int step, enum target_signal sig) /* Allow continuing with the same signal that interrupted us. Otherwise complain. */ - child_continue (continue_status, pid); + win32_continue (continue_status, pid); } static void -child_prepare_to_store (void) +win32_prepare_to_store (void) { /* Do nothing, since we can store individual regs */ } static int -child_can_run (void) +win32_can_run (void) { return 1; } static void -child_close (int x) +win32_close (int x) { - DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n", + DEBUG_EVENTS (("gdb: win32_close, inferior_ptid=%d\n", PIDGET (inferior_ptid))); } +/* Convert pid to printable format. */ +static char * +cygwin_pid_to_str (ptid_t ptid) +{ + static char buf[80]; + int pid = PIDGET (ptid); + + if ((DWORD) pid == current_event.dwProcessId) + sprintf (buf, "process %d", pid); + else + sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid); + return buf; +} + static void -init_child_ops (void) -{ - deprecated_child_ops.to_shortname = "child"; - deprecated_child_ops.to_longname = "Win32 child process"; - deprecated_child_ops.to_doc = "Win32 child process (started by the \"run\" command)."; - deprecated_child_ops.to_open = child_open; - deprecated_child_ops.to_close = child_close; - deprecated_child_ops.to_attach = child_attach; - deprecated_child_ops.to_detach = child_detach; - deprecated_child_ops.to_resume = child_resume; - deprecated_child_ops.to_wait = child_wait; - deprecated_child_ops.to_fetch_registers = child_fetch_inferior_registers; - deprecated_child_ops.to_store_registers = child_store_inferior_registers; - deprecated_child_ops.to_prepare_to_store = child_prepare_to_store; - deprecated_child_ops.deprecated_xfer_memory = child_xfer_memory; - deprecated_child_ops.to_files_info = child_files_info; - deprecated_child_ops.to_insert_breakpoint = memory_insert_breakpoint; - deprecated_child_ops.to_remove_breakpoint = memory_remove_breakpoint; - deprecated_child_ops.to_terminal_init = terminal_init_inferior; - deprecated_child_ops.to_terminal_inferior = terminal_inferior; - deprecated_child_ops.to_terminal_ours_for_output = terminal_ours_for_output; - deprecated_child_ops.to_terminal_ours = terminal_ours; - deprecated_child_ops.to_terminal_save_ours = terminal_save_ours; - deprecated_child_ops.to_terminal_info = child_terminal_info; - deprecated_child_ops.to_kill = child_kill_inferior; - deprecated_child_ops.to_create_inferior = child_create_inferior; - deprecated_child_ops.to_mourn_inferior = child_mourn_inferior; - deprecated_child_ops.to_can_run = child_can_run; - deprecated_child_ops.to_thread_alive = win32_child_thread_alive; - deprecated_child_ops.to_pid_to_str = cygwin_pid_to_str; - deprecated_child_ops.to_stop = child_stop; - deprecated_child_ops.to_stratum = process_stratum; - deprecated_child_ops.to_has_all_memory = 1; - deprecated_child_ops.to_has_memory = 1; - deprecated_child_ops.to_has_stack = 1; - deprecated_child_ops.to_has_registers = 1; - deprecated_child_ops.to_has_execution = 1; - deprecated_child_ops.to_magic = OPS_MAGIC; - deprecated_child_ops.to_pid_to_exec_file = child_pid_to_exec_file; +init_win32_ops (void) +{ + win32_ops.to_shortname = "child"; + win32_ops.to_longname = "Win32 child process"; + win32_ops.to_doc = "Win32 child process (started by the \"run\" command)."; + win32_ops.to_open = win32_open; + win32_ops.to_close = win32_close; + win32_ops.to_attach = win32_attach; + win32_ops.to_detach = win32_detach; + win32_ops.to_resume = win32_resume; + win32_ops.to_wait = win32_wait; + win32_ops.to_fetch_registers = win32_fetch_inferior_registers; + win32_ops.to_store_registers = win32_store_inferior_registers; + win32_ops.to_prepare_to_store = win32_prepare_to_store; + win32_ops.deprecated_xfer_memory = win32_xfer_memory; + win32_ops.to_files_info = win32_files_info; + win32_ops.to_insert_breakpoint = memory_insert_breakpoint; + win32_ops.to_remove_breakpoint = memory_remove_breakpoint; + win32_ops.to_terminal_init = terminal_init_inferior; + win32_ops.to_terminal_inferior = terminal_inferior; + win32_ops.to_terminal_ours_for_output = terminal_ours_for_output; + win32_ops.to_terminal_ours = terminal_ours; + win32_ops.to_terminal_save_ours = terminal_save_ours; + win32_ops.to_terminal_info = child_terminal_info; + win32_ops.to_kill = win32_kill_inferior; + win32_ops.to_create_inferior = win32_create_inferior; + win32_ops.to_mourn_inferior = win32_mourn_inferior; + win32_ops.to_can_run = win32_can_run; + win32_ops.to_thread_alive = win32_win32_thread_alive; + win32_ops.to_pid_to_str = cygwin_pid_to_str; + win32_ops.to_stop = win32_stop; + win32_ops.to_stratum = process_stratum; + win32_ops.to_has_all_memory = 1; + win32_ops.to_has_memory = 1; + win32_ops.to_has_stack = 1; + win32_ops.to_has_registers = 1; + win32_ops.to_has_execution = 1; + win32_ops.to_magic = OPS_MAGIC; + win32_ops.to_pid_to_exec_file = win32_pid_to_exec_file; + + win32_so_ops.relocate_section_addresses = win32_relocate_section_addresses; + win32_so_ops.free_so = win32_free_so; + win32_so_ops.clear_solib = win32_clear_solib; + win32_so_ops.solib_create_inferior_hook = NULL; + win32_so_ops.special_symbol_handling = NULL; + win32_so_ops.current_sos = win32_current_sos; + win32_so_ops.open_symbol_file_object = NULL; + win32_so_ops.in_dynsym_resolve_code = NULL; + + /* FIXME: Don't do this here. *_gdbarch_init() should set so_ops. */ + current_target_so_ops = &win32_so_ops; } void @@ -2127,7 +2047,7 @@ _initialize_win32_nat (void) { struct cmd_list_element *c; - init_child_ops (); + init_win32_ops (); c = add_com ("dll-symbols", class_files, dll_symbol_command, _("Load dll library symbols from FILE.")); @@ -2195,15 +2115,14 @@ Show whether to display kernel exceptions in child process."), NULL, add_cmd ("selector", class_info, display_selectors, _("Display selectors infos."), &info_w32_cmdlist); - - add_target (&deprecated_child_ops); + add_target (&win32_ops); } /* Hardware watchpoint support, adapted from go32-nat.c code. */ /* Pass the address ADDR to the inferior in the I'th debug register. Here we just store the address in dr array, the registers will be - actually set up when child_continue is called. */ + actually set up when win32_continue is called. */ void cygwin_set_dr (int i, CORE_ADDR addr) { @@ -2217,7 +2136,7 @@ cygwin_set_dr (int i, CORE_ADDR addr) /* Pass the value VAL to the inferior in the DR7 debug control register. Here we just store the address in D_REGS, the watchpoint - will be actually set up in child_wait. */ + will be actually set up in win32_wait. */ void cygwin_set_dr7 (unsigned val) { @@ -2239,7 +2158,7 @@ cygwin_get_dr6 (void) by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0 it means that the pid has died. Otherwise it is assumed to be alive. */ static int -win32_child_thread_alive (ptid_t ptid) +win32_win32_thread_alive (ptid_t ptid) { int pid = PIDGET (ptid); @@ -2247,206 +2166,6 @@ win32_child_thread_alive (ptid_t ptid) FALSE : TRUE; } -/* Convert pid to printable format. */ -char * -cygwin_pid_to_str (ptid_t ptid) -{ - static char buf[80]; - int pid = PIDGET (ptid); - - if ((DWORD) pid == current_event.dwProcessId) - sprintf (buf, "process %d", pid); - else - sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid); - return buf; -} - -static int -core_dll_symbols_add (char *dll_name, DWORD base_addr) -{ - struct objfile *objfile; - char *objfile_basename; - const char *dll_basename; - - if (!(dll_basename = strrchr (dll_name, '/'))) - dll_basename = dll_name; - else - dll_basename++; - - ALL_OBJFILES (objfile) - { - objfile_basename = strrchr (objfile->name, '/'); - - if (objfile_basename && - strcmp (dll_basename, objfile_basename + 1) == 0) - { - printf_unfiltered ("%08lx:%s (symbols previously loaded)\n", - base_addr, dll_name); - goto out; - } - } - - register_loaded_dll (dll_name, base_addr + 0x1000); - solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000); - - out: - return 1; -} - -typedef struct -{ - struct target_ops *target; - bfd_vma addr; -} map_code_section_args; - -static void -map_single_dll_code_section (bfd * abfd, asection * sect, void *obj) -{ - int old; - int update_coreops; - struct section_table *new_target_sect_ptr; - - map_code_section_args *args = (map_code_section_args *) obj; - struct target_ops *target = args->target; - if (sect->flags & SEC_CODE) - { - update_coreops = core_ops.to_sections == target->to_sections; - - if (target->to_sections) - { - old = target->to_sections_end - target->to_sections; - target->to_sections = (struct section_table *) - xrealloc ((char *) target->to_sections, - (sizeof (struct section_table)) * (1 + old)); - } - else - { - old = 0; - target->to_sections = (struct section_table *) - xmalloc ((sizeof (struct section_table))); - } - target->to_sections_end = target->to_sections + (1 + old); - - /* Update the to_sections field in the core_ops structure - if needed. */ - if (update_coreops) - { - core_ops.to_sections = target->to_sections; - core_ops.to_sections_end = target->to_sections_end; - } - new_target_sect_ptr = target->to_sections + old; - new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect); - new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) + - bfd_section_size (abfd, sect);; - new_target_sect_ptr->the_bfd_section = sect; - new_target_sect_ptr->bfd = abfd; - } -} - -static int -dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target) -{ - bfd *dll_bfd; - map_code_section_args map_args; - asection *lowest_sect; - char *name; - if (dll_name == NULL || target == NULL) - return 0; - name = xstrdup (dll_name); - dll_bfd = bfd_openr (name, "pei-i386"); - if (dll_bfd == NULL) - return 0; - - if (bfd_check_format (dll_bfd, bfd_object)) - { - lowest_sect = bfd_get_section_by_name (dll_bfd, ".text"); - if (lowest_sect == NULL) - return 0; - map_args.target = target; - map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect); - - bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args)); - } - - return 1; -} - -static void -core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj) -{ - struct target_ops *target = (struct target_ops *) obj; - - DWORD base_addr; - - int dll_name_size; - char *dll_name = NULL; - char *buf = NULL; - struct win32_pstatus *pstatus; - char *p; - - if (strncmp (sect->name, ".module", 7)) - return; - - buf = (char *) xmalloc (bfd_get_section_size (sect) + 1); - if (!buf) - { - printf_unfiltered ("memory allocation failed for %s\n", sect->name); - goto out; - } - if (!bfd_get_section_contents (abfd, sect, buf, 0, bfd_get_section_size (sect))) - goto out; - - pstatus = (struct win32_pstatus *) buf; - - memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr)); - dll_name_size = pstatus->data.module_info.module_name_size; - if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > bfd_get_section_size (sect)) - goto out; - - dll_name = (char *) xmalloc (dll_name_size + 1); - if (!dll_name) - { - printf_unfiltered ("memory allocation failed for %s\n", sect->name); - goto out; - } - strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size); - - while ((p = strchr (dll_name, '\\'))) - *p = '/'; - - if (!core_dll_symbols_add (dll_name, (DWORD) base_addr)) - printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name); - - if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target)) - printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name); - -out: - if (buf) - xfree (buf); - if (dll_name) - xfree (dll_name); - return; -} - -void -child_solib_add (char *filename, int from_tty, struct target_ops *target, - int readsyms) -{ - if (!readsyms) - return; - if (core_bfd) - { - child_clear_solibs (); - bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target); - } - else - { - if (solib_end && solib_end->name) - solib_end->objfile = solib_symbols_add (solib_end->name, from_tty, - solib_end->load_addr); - } -} - static void fetch_elf_core_registers (char *core_reg_sect, unsigned core_reg_size, |