/* Target-vector operations for controlling win32 child processes, for GDB.
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free
+ Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Free
Software Foundation, Inc.
Contributed by Cygnus Solutions, A Red Hat Company.
static HANDLE current_process_handle; /* Currently executing process */
static thread_info *current_thread; /* Info on currently selected thread */
static DWORD main_thread_id; /* Thread ID of the main thread */
-static pid_t cygwin_pid; /* pid of cygwin process */
/* Counts of things. */
static int exception_count = 0;
do_child_store_inferior_registers (int r)
{
if (r >= 0)
- deprecated_read_register_gen (r, ((char *) ¤t_thread->context) + mappings[r]);
+ regcache_collect (r, ((char *) ¤t_thread->context) + mappings[r]);
else
{
for (r = 0; r < NUM_REGS; r++)
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)))
+ 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 */
if (address == NULL)
return NULL;
- ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done);
-
/* See if we could read the address of a string, and that the
address isn't null. */
-
- if (done != sizeof (address_ptr) || !address_ptr)
+ if (!ReadProcessMemory (h, address, &address_ptr, sizeof (address_ptr), &done)
+ || done != sizeof (address_ptr) || !address_ptr)
return NULL;
/* Find the length of the string */
- do
- {
- ReadProcessMemory (h, address_ptr + len * size, &b, size, &done);
- len++;
- }
- while ((b[0] != 0 || b[size - 1] != 0) && done == size);
+ while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
+ && (b[0] != 0 || b[size - 1] != 0) && done == size)
+ continue;
if (!unicode)
ReadProcessMemory (h, address_ptr, buf, len, &done);
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 section_addrs;
+ struct section_addr_info *section_addrs_ptr = 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
if (!name || !name[0])
return NULL;
- 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, §ion_addrs, 0, OBJF_SHARED);
+ 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))
+ {
+ section_addrs_ptr = get_relocated_section_addrs (abfd, load_addr);
+ }
+
+ bfd_close (abfd);
+ }
+
+ if (section_addrs_ptr)
+ {
+ result = safe_symbol_file_add (name, from_tty, section_addrs_ptr,
+ 0, OBJF_SHARED);
+
+ free_section_addr_info (section_addrs_ptr);
+ }
+
+ else
+ {
+ /* Fallback on handling just the .text section. */
+ struct section_addr_info section_addrs;
+
+ memset (§ion_addrs, 0, sizeof (section_addrs));
+ section_addrs.other[0].name = ".text";
+ section_addrs.other[0].addr = load_addr;
+
+ result = safe_symbol_file_add (name, from_tty, §ion_addrs,
+ 0, OBJF_SHARED);
+ }
+
+ return result;
}
/* Load DLL symbol info. */
int base, limit;
printf_filtered ("0x%03lx: ", sel);
if (!info.HighWord.Bits.Pres)
- {
- puts_filtered ("Segment not present\n");
- return 0;
- }
+ {
+ puts_filtered ("Segment not present\n");
+ return 0;
+ }
base = (info.HighWord.Bits.BaseHi << 24) +
(info.HighWord.Bits.BaseMid << 16)
+ info.BaseLow;
limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
if (info.HighWord.Bits.Granularity)
- limit = (limit << 12) | 0xfff;
+ limit = (limit << 12) | 0xfff;
printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
if (info.HighWord.Bits.Default_Big)
- puts_filtered(" 32-bit ");
+ puts_filtered(" 32-bit ");
else
- puts_filtered(" 16-bit ");
+ puts_filtered(" 16-bit ");
switch ((info.HighWord.Bits.Type & 0xf) >> 1)
{
case 0:
- puts_filtered ("Data (Read-Only, Exp-up");
- break;
+ puts_filtered ("Data (Read-Only, Exp-up");
+ break;
case 1:
- puts_filtered ("Data (Read/Write, Exp-up");
- break;
+ puts_filtered ("Data (Read/Write, Exp-up");
+ break;
case 2:
- puts_filtered ("Unused segment (");
- break;
+ puts_filtered ("Unused segment (");
+ break;
case 3:
- puts_filtered ("Data (Read/Write, Exp-down");
- break;
+ puts_filtered ("Data (Read/Write, Exp-down");
+ break;
case 4:
- puts_filtered ("Code (Exec-Only, N.Conf");
- break;
+ puts_filtered ("Code (Exec-Only, N.Conf");
+ break;
case 5:
- puts_filtered ("Code (Exec/Read, N.Conf");
+ puts_filtered ("Code (Exec/Read, N.Conf");
break;
case 6:
- puts_filtered ("Code (Exec-Only, Conf");
+ puts_filtered ("Code (Exec-Only, Conf");
break;
case 7:
- puts_filtered ("Code (Exec/Read, Conf");
+ puts_filtered ("Code (Exec/Read, Conf");
break;
default:
printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
}
if ((info.HighWord.Bits.Type & 0x1) == 0)
- puts_filtered(", N.Acc");
+ puts_filtered(", N.Acc");
puts_filtered (")\n");
if ((info.HighWord.Bits.Type & 0x10) == 0)
puts_filtered("System selector ");
printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
if (info.HighWord.Bits.Granularity)
- puts_filtered ("Page granular.\n");
+ puts_filtered ("Page granular.\n");
else
puts_filtered ("Byte granular.\n");
return 1;
puts_filtered ("Selector $cs\n");
display_selector (current_thread->h,
- current_thread->context.SegCs);
+ current_thread->context.SegCs);
puts_filtered ("Selector $ds\n");
display_selector (current_thread->h,
- current_thread->context.SegDs);
+ current_thread->context.SegDs);
puts_filtered ("Selector $es\n");
display_selector (current_thread->h,
- current_thread->context.SegEs);
+ current_thread->context.SegEs);
puts_filtered ("Selector $ss\n");
display_selector (current_thread->h,
- current_thread->context.SegSs);
+ current_thread->context.SegSs);
puts_filtered ("Selector $fs\n");
display_selector (current_thread->h,
current_thread->context.SegFs);
puts_filtered ("Selector $gs\n");
display_selector (current_thread->h,
- current_thread->context.SegGs);
+ current_thread->context.SegGs);
}
else
{
AdjustTokenPrivileges = GetProcAddress (advapi32,
"AdjustTokenPrivileges");
if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
- {
+ {
advapi32 = NULL;
goto out;
}
}
-
+
if (!OpenProcessToken (GetCurrentProcess (),
TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
&token_hdl))
new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
- sizeof orig_priv, &orig_priv, &size))
+ sizeof orig_priv, &orig_priv, &size))
goto out;
#if 0
/* Disabled, otherwise every `attach' in an unprivileged user session
printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
}
- pid = strtoul (args, 0, 0);
+ pid = strtoul (args, 0, 0); /* Windows pid */
+
ok = DebugActiveProcess (pid);
saw_create = 0;
if (!ok)
- error ("Can't attach to process.");
+ {
+ /* Try fall back to Cygwin pid */
+ pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
+
+ if (pid > 0)
+ ok = DebugActiveProcess (pid);
+
+ if (!ok)
+ error ("Can't attach to process.");
+ }
if (has_detach_ability ())
{
int write, struct mem_attrib *mem,
struct target_ops *target)
{
- DWORD done;
+ DWORD done = 0;
if (write)
{
DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
len, (DWORD) memaddr));
- WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
- len, &done);
+ if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
+ len, &done))
+ done = 0;
FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
}
else
{
DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
len, (DWORD) memaddr));
- ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
- &done);
+ if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
+ len, &done))
+ done = 0;
}
return done;
}
if (th->context.ContextFlags)
{
- if (debug_registers_changed)
- {
- th->context.Dr0 = dr[0];
- th->context.Dr1 = dr[1];
- th->context.Dr2 = dr[2];
- th->context.Dr3 = dr[3];
- /* th->context.Dr6 = dr[6];
- FIXME: should we set dr6 also ?? */
- th->context.Dr7 = dr[7];
- }
+ if (debug_registers_changed)
+ {
+ th->context.Dr0 = dr[0];
+ th->context.Dr1 = dr[1];
+ th->context.Dr2 = dr[2];
+ th->context.Dr3 = dr[3];
+ /* th->context.Dr6 = dr[6];
+ FIXME: should we set dr6 also ?? */
+ th->context.Dr7 = dr[7];
+ }
CHECK (SetThreadContext (th->h, &th->context));
th->context.ContextFlags = 0;
}
add_info_alias ("sharedlibrary", "dll", 1);
add_prefix_cmd ("w32", class_info, info_w32_command,
- "Print information specific to Win32 debugging.",
- &info_w32_cmdlist, "info w32 ", 0, &infolist);
+ "Print information specific to Win32 debugging.",
+ &info_w32_cmdlist, "info w32 ", 0, &infolist);
add_cmd ("selector", class_info, display_selectors,
- "Display selectors infos.",
+ "Display selectors infos.",
&info_w32_cmdlist);
add_target (&child_ops);