[RFA] solib-svr4.c fetch link map address

Elena Zannoni
2002-10-02T02:30:30Z

This function is used by thread_db.c. Gdb needs to pass the address of
the link map to glibc. Glibc will compute the address of a thread
local variable, given such address and the offset within the thread
local storage at which the variable is stored (gdb gets the offset out
of the debug info).

The interface for the glibc function is like this:

extern td_err_e td_thr_tls_get_addr (const td_thrhandle_t *__th,
void *__map_address, size_t __offset,
void **__address);

The function loops through the link maps, and returns the address of
the one corresponding to the given objfile. Note that this function
takes into account that objfile can be the main executable, not just a
shared library. The main executable has always an empty name field in
the linkmap.

Elena

2002-10-01 Elena Zannoni <ezannoni@redhat.com>

* solib-svr4.c (svr4_fetch_objfile_link_map): New function.
* solib-svr4.h (svr4_fetch_objfile_link_map): Export.

Index: solib-svr4.h
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.h,v
retrieving revision 1.3
diff -u -p -r1.3 solib-svr4.h
--- solib-svr4.h 26 Sep 2001 07:03:13 -0000 1.3
+++ solib-svr4.h 2 Oct 2002 02:28:55 -0000
@@ -72,6 +72,10 @@ struct link_map_offsets
extern void set_solib_svr4_fetch_link_map_offsets
(struct gdbarch *gdbarch, struct link_map_offsets *(*func) (void));

+/* This function is called by thread_db.c. Return the address of the
+ link map for the given objfile. */
+extern CORE_ADDR svr4_fetch_objfile_link_map (struct objfile *objfile);
+
/* legacy_svr4_fetch_link_map_offsets_hook is a pointer to a function
which is used to fetch link map offsets. It will only be set
by solib-legacy.c, if at all. */

Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.26
diff -u -p -r1.26 solib-svr4.c
--- solib-svr4.c 9 Jun 2002 16:39:00 -0000 1.26
+++ solib-svr4.c 2 Oct 2002 02:27:19 -0000
@@ -762,6 +762,75 @@ svr4_current_sos (void)
return head;
}

+/* Get the address of the link_map for a given OBJFILE. Loop through
+ the link maps, and return the address of the one corresponding to
+ the given objfile. Note that this function takes into account that
+ objfile can be the main executable, not just a shared library. The
+ main executable has always an empty name field in the linkmap. */
+
+CORE_ADDR
+svr4_fetch_objfile_link_map (struct objfile *objfile)
+{
+ CORE_ADDR lm;
+
+ if ((debug_base = locate_base ()) == 0)
+ return 0; /* failed somehow... */
+
+ /* Position ourselves on the first link map. */
+ lm = first_link_map_member ();
+ while (lm)
+ {
+ /* Get info on the layout of the r_debug and link_map structures. */
+ struct link_map_offsets *lmo = SVR4_FETCH_LINK_MAP_OFFSETS ();
+ int errcode;
+ char *buffer;
+ struct lm_info objfile_lm_info;
+ struct cleanup *old_chain;
+ CORE_ADDR name_address;
+ char *l_name_buf = xmalloc (lmo->l_name_size);
+
+ /* Set up the buffer to contain the portion of the link_map
+ structure that gdb cares about. Note that this is not the
+ whole link_map structure. */
+ objfile_lm_info.lm = xmalloc (lmo->link_map_size);
+ old_chain = make_cleanup (xfree, objfile_lm_info.lm);
+ memset (objfile_lm_info.lm, 0, lmo->link_map_size);
+
+ /* Read the link map into our internal structure. */
+ read_memory (lm, objfile_lm_info.lm, lmo->link_map_size);
+
+ /* Read address of name from target memory to GDB. */
+ read_memory (lm + lmo->l_name_offset, l_name_buf, lmo->l_name_size);
+
+ /* Extract this object's name. */
+ name_address = extract_address (l_name_buf,
+ lmo->l_name_size);
+ target_read_string (name_address, &buffer,
+ SO_NAME_MAX_PATH_SIZE - 1, &errcode);
+ if (errcode != 0)
+ {
+ warning ("svr4_fetch_objfile_link_map: Can't read pathname for load map: %s\n",
+ safe_strerror (errcode));
+ }
+ else
+ {
+ /* Is this the linkmap for the file we want? */
+ /* If the file is not a shared library and has no name,
+ we are sure it is the main executable, so we return that. */
+ if ((buffer && strcmp (buffer, objfile->name) == 0)
+ || (!(objfile->flags & OBJF_SHARED) && (strcmp (buffer, "") == 0)))
+ {
+ discard_cleanups (old_chain);
+ return lm;
+ }
+ }
+ /* Not the file we wanted, continue checking. */
+ lm = extract_address (objfile_lm_info.lm + lmo->l_next_offset,
+ lmo->l_next_size);
+ discard_cleanups (old_chain);
+ }
+ return 0;
+}

/* On some systems, the only way to recognize the link map entry for
the main executable file is by looking at its name. Return