Simplify windows-nat.c solib handling
Currently windows-nat.c uses struct so_list to record its local idea of which shared libraries have been loaded. However, many fields in this are not needed, and furthermore I found this quite confusing at first -- Windows actually uses solib-target and so the use of so_list here is weird. This patch simplifies this code by changing it to use a std::vector and a new type that holds exactly what's needed for the Windows code.
This commit is contained in:
parent
4994e74b7a
commit
85b25bd975
1 changed files with 49 additions and 66 deletions
|
@ -641,18 +641,24 @@ windows_nat_target::store_registers (struct regcache *regcache, int r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Maintain a linked list of "so" information. */
|
/* Maintain a linked list of "so" information. */
|
||||||
struct lm_info_windows : public lm_info_base
|
struct windows_solib
|
||||||
{
|
{
|
||||||
LPVOID load_addr = 0;
|
LPVOID load_addr = 0;
|
||||||
CORE_ADDR text_offset = 0;
|
CORE_ADDR text_offset = 0;
|
||||||
|
|
||||||
|
/* Original name. */
|
||||||
|
std::string original_name;
|
||||||
|
/* Expanded form of the name. */
|
||||||
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct so_list solib_start, *solib_end;
|
static std::vector<windows_solib> solibs;
|
||||||
|
|
||||||
static struct so_list *
|
/* See nat/windows-nat.h. */
|
||||||
|
|
||||||
|
static windows_solib *
|
||||||
windows_make_so (const char *name, LPVOID load_addr)
|
windows_make_so (const char *name, LPVOID load_addr)
|
||||||
{
|
{
|
||||||
struct so_list *so;
|
|
||||||
char *p;
|
char *p;
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
char buf[__PMAX];
|
char buf[__PMAX];
|
||||||
|
@ -701,38 +707,43 @@ windows_make_so (const char *name, LPVOID load_addr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
so = XCNEW (struct so_list);
|
solibs.emplace_back ();
|
||||||
lm_info_windows *li = new lm_info_windows;
|
windows_solib *so = &solibs.back ();
|
||||||
so->lm_info = li;
|
so->load_addr = load_addr;
|
||||||
li->load_addr = load_addr;
|
so->original_name = name;
|
||||||
strcpy (so->so_original_name, name);
|
|
||||||
#ifndef __CYGWIN__
|
#ifndef __CYGWIN__
|
||||||
strcpy (so->so_name, buf);
|
so->name = buf;
|
||||||
#else
|
#else
|
||||||
if (buf[0])
|
if (buf[0])
|
||||||
cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, so->so_name,
|
{
|
||||||
|
char name[SO_NAME_MAX_PATH_SIZE];
|
||||||
|
cygwin_conv_path (CCP_WIN_W_TO_POSIX, buf, name,
|
||||||
SO_NAME_MAX_PATH_SIZE);
|
SO_NAME_MAX_PATH_SIZE);
|
||||||
|
so->name = name;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *rname = realpath (name, NULL);
|
char *rname = realpath (name, NULL);
|
||||||
if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
|
if (rname && strlen (rname) < SO_NAME_MAX_PATH_SIZE)
|
||||||
{
|
{
|
||||||
strcpy (so->so_name, rname);
|
so->name = rname;
|
||||||
free (rname);
|
free (rname);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
warning (_("dll path for \"%s\" too long or inaccessible"), name);
|
warning (_("dll path for \"%s\" too long or inaccessible"), name);
|
||||||
strcpy (so->so_name, so->so_original_name);
|
so->name = so->original_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Record cygwin1.dll .text start/end. */
|
/* Record cygwin1.dll .text start/end. */
|
||||||
p = strchr (so->so_name, '\0') - (sizeof ("/cygwin1.dll") - 1);
|
size_t len = sizeof ("/cygwin1.dll") - 1;
|
||||||
if (p >= so->so_name && strcasecmp (p, "/cygwin1.dll") == 0)
|
if (so->name.size () >= len
|
||||||
|
&& strcasecmp (so->name.c_str () + so->name.size () - len,
|
||||||
|
"/cygwin1.dll") == 0)
|
||||||
{
|
{
|
||||||
asection *text = NULL;
|
asection *text = NULL;
|
||||||
|
|
||||||
gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->so_name, "pei-i386"));
|
gdb_bfd_ref_ptr abfd (gdb_bfd_open (so->name, "pei-i386"));
|
||||||
|
|
||||||
if (abfd == NULL)
|
if (abfd == NULL)
|
||||||
return so;
|
return so;
|
||||||
|
@ -760,22 +771,9 @@ windows_make_so (const char *name, LPVOID load_addr)
|
||||||
void
|
void
|
||||||
windows_nat::handle_load_dll (const char *dll_name, LPVOID base)
|
windows_nat::handle_load_dll (const char *dll_name, LPVOID base)
|
||||||
{
|
{
|
||||||
solib_end->next = windows_make_so (dll_name, base);
|
windows_solib *solib = windows_make_so (dll_name, base);
|
||||||
solib_end = solib_end->next;
|
DEBUG_EVENTS ("Loading dll \"%s\" at %s.", solib->name.c_str (),
|
||||||
|
host_address_to_string (solib->load_addr));
|
||||||
lm_info_windows *li = (lm_info_windows *) solib_end->lm_info;
|
|
||||||
|
|
||||||
DEBUG_EVENTS ("Loading dll \"%s\" at %s.", solib_end->so_name,
|
|
||||||
host_address_to_string (li->load_addr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
windows_free_so (struct so_list *so)
|
|
||||||
{
|
|
||||||
lm_info_windows *li = (lm_info_windows *) so->lm_info;
|
|
||||||
|
|
||||||
delete li;
|
|
||||||
xfree (so);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See nat/windows-nat.h. */
|
/* See nat/windows-nat.h. */
|
||||||
|
@ -784,24 +782,22 @@ void
|
||||||
windows_nat::handle_unload_dll ()
|
windows_nat::handle_unload_dll ()
|
||||||
{
|
{
|
||||||
LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
|
LPVOID lpBaseOfDll = current_event.u.UnloadDll.lpBaseOfDll;
|
||||||
struct so_list *so;
|
|
||||||
|
|
||||||
for (so = &solib_start; so->next != NULL; so = so->next)
|
auto iter = std::remove_if (solibs.begin (), solibs.end (),
|
||||||
|
[&] (windows_solib &lib)
|
||||||
{
|
{
|
||||||
lm_info_windows *li_next = (lm_info_windows *) so->next->lm_info;
|
if (lib.load_addr == lpBaseOfDll)
|
||||||
|
|
||||||
if (li_next->load_addr == lpBaseOfDll)
|
|
||||||
{
|
{
|
||||||
struct so_list *sodel = so->next;
|
DEBUG_EVENTS ("Unloading dll \"%s\".", lib.name.c_str ());
|
||||||
|
return true;
|
||||||
so->next = sodel->next;
|
|
||||||
if (!so->next)
|
|
||||||
solib_end = so;
|
|
||||||
DEBUG_EVENTS ("Unloading dll \"%s\".", sodel->so_name);
|
|
||||||
|
|
||||||
windows_free_so (sodel);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (iter != solibs.end ())
|
||||||
|
{
|
||||||
|
solibs.erase (iter, solibs.end ());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We did not find any DLL that was previously loaded at this address,
|
/* We did not find any DLL that was previously loaded at this address,
|
||||||
|
@ -835,15 +831,7 @@ catch_errors (void (*func) ())
|
||||||
static void
|
static void
|
||||||
windows_clear_solib (void)
|
windows_clear_solib (void)
|
||||||
{
|
{
|
||||||
struct so_list *so;
|
solibs.clear ();
|
||||||
|
|
||||||
for (so = solib_start.next; so; so = solib_start.next)
|
|
||||||
{
|
|
||||||
solib_start.next = so->next;
|
|
||||||
windows_free_so (so);
|
|
||||||
}
|
|
||||||
|
|
||||||
solib_end = &solib_start;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -2892,22 +2880,17 @@ windows_xfer_shared_libraries (struct target_ops *ops,
|
||||||
struct obstack obstack;
|
struct obstack obstack;
|
||||||
const char *buf;
|
const char *buf;
|
||||||
LONGEST len_avail;
|
LONGEST len_avail;
|
||||||
struct so_list *so;
|
|
||||||
|
|
||||||
if (writebuf)
|
if (writebuf)
|
||||||
return TARGET_XFER_E_IO;
|
return TARGET_XFER_E_IO;
|
||||||
|
|
||||||
obstack_init (&obstack);
|
obstack_init (&obstack);
|
||||||
obstack_grow_str (&obstack, "<library-list>\n");
|
obstack_grow_str (&obstack, "<library-list>\n");
|
||||||
for (so = solib_start.next; so; so = so->next)
|
for (windows_solib &so : solibs)
|
||||||
{
|
windows_xfer_shared_library (so.name.c_str (),
|
||||||
lm_info_windows *li = (lm_info_windows *) so->lm_info;
|
(CORE_ADDR) (uintptr_t) so.load_addr,
|
||||||
|
&so.text_offset,
|
||||||
windows_xfer_shared_library (so->so_name, (CORE_ADDR)
|
|
||||||
(uintptr_t) li->load_addr,
|
|
||||||
&li->text_offset,
|
|
||||||
target_gdbarch (), &obstack);
|
target_gdbarch (), &obstack);
|
||||||
}
|
|
||||||
obstack_grow_str0 (&obstack, "</library-list>\n");
|
obstack_grow_str0 (&obstack, "</library-list>\n");
|
||||||
|
|
||||||
buf = (const char *) obstack_finish (&obstack);
|
buf = (const char *) obstack_finish (&obstack);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue