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

Elena Zannoni
2002-10-21T18:43:16Z

Elena Zannoni writes:
>
> 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.
>

I committed the following.

Elena

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 21 Oct 2002 14:55:53 -0000
@@ -762,6 +762,77 @@ 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);
+ old_chain = make_cleanup (xfree, l_name_buf);
+
+ /* 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);
+ 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);
+ make_cleanup (xfree, buffer);
+ 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)))
+ {
+ do_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);
+ do_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