⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 solib.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    {      bfd_close (interp_bfd);      return (0);    }  /* Eureka!  We found the symbol.  But now we may need to relocate it     by the base address.  If the symbol's value is less than the base     address of the shared library, then it hasn't yet been relocated     by the dynamic linker, and we have to do it ourself.  FIXME: Note     that we make the assumption that the first segment that corresponds     to the shared library has the base address to which the library     was relocated. */  if (address < baseaddr)    {      address += baseaddr;    }  debug_base = address;  bfd_close (interp_bfd);  return (1);}#endif/*LOCAL FUNCTION	locate_base -- locate the base address of dynamic linker structsSYNOPSIS	CORE_ADDR locate_base (void)DESCRIPTION	For both the SunOS and SVR4 shared library implementations, if the	inferior executable has been linked dynamically, there is a single	address somewhere in the inferior's data space which is the key to	locating all of the dynamic linker's runtime structures.  This	address is the value of the symbol defined by the macro DEBUG_BASE.	The job of this function is to find and return that address, or to	return 0 if there is no such address (the executable is statically	linked for example).	For SunOS, the job is almost trivial, since the dynamic linker and	all of it's structures are statically linked to the executable at	link time.  Thus the symbol for the address we are looking for has	already been added to the minimal symbol table for the executable's	objfile at the time the symbol file's symbols were read, and all we	have to do is look it up there.  Note that we explicitly do NOT want	to find the copies in the shared library.	The SVR4 version is much more complicated because the dynamic linker	and it's structures are located in the shared C library, which gets	run as the executable's "interpreter" by the kernel.  We have to go	to a lot more work to discover the address of DEBUG_BASE.  Because	of this complexity, we cache the value we find and return that value	on subsequent invocations.  Note there is no copy in the executable	symbol tables.	Note that we can assume nothing about the process state at the time	we need to find this address.  We may be stopped on the first instruc-	tion of the interpreter (C shared library), the first instruction of	the executable itself, or somewhere else entirely (if we attached	to the process for example). */static CORE_ADDRlocate_base (){#ifndef SVR4_SHARED_LIBS  struct minimal_symbol *msymbol;  CORE_ADDR address = 0;  /* For SunOS, we want to limit the search for DEBUG_BASE to the executable     being debugged, since there is a duplicate named symbol in the shared     library.  We don't want the shared library versions. */  msymbol = lookup_minimal_symbol (DEBUG_BASE, symfile_objfile);  if ((msymbol != NULL) && (msymbol -> address != 0))    {      address = msymbol -> address;    }  return (address);#else	/* SVR4_SHARED_LIBS */  /* Check to see if we have a currently valid address, and if so, avoid     doing all this work again and just return the cached address.  If     we have no cached address, ask the /proc support interface to iterate     over the list of mapped address segments, calling look_for_base() for     each segment.  When we are done, we will have either found the base     address or not. */  if (debug_base == 0)    {      proc_iterate_over_mappings (look_for_base);    }  return (debug_base);#endif	/* !SVR4_SHARED_LIBS */}static struct link_map *first_link_map_member (){  struct link_map *lm = NULL;#ifndef SVR4_SHARED_LIBS  read_memory (debug_base, (char *) &dynamic_copy, sizeof (dynamic_copy));  if (dynamic_copy.ld_version >= 2)    {      /* It is a version that we can deal with, so read in the secondary	 structure and find the address of the link map list from it. */      read_memory ((CORE_ADDR) dynamic_copy.ld_un.ld_2, (char *) &ld_2_copy,		   sizeof (struct link_dynamic_2));      lm = ld_2_copy.ld_loaded;    }#else	/* SVR4_SHARED_LIBS */  read_memory (debug_base, (char *) &debug_copy, sizeof (struct r_debug));  lm = debug_copy.r_map;#endif	/* !SVR4_SHARED_LIBS */  return (lm);}/*LOCAL FUNCTION	find_solib -- step through list of shared objectsSYNOPSIS	struct so_list *find_solib (struct so_list *so_list_ptr)DESCRIPTION	This module contains the routine which finds the names of any	loaded "images" in the current process. The argument in must be	NULL on the first call, and then the returned value must be passed	in on subsequent calls. This provides the capability to "step" down	the list of loaded objects. On the last object, a NULL value is	returned.	The arg and return value are "struct link_map" pointers, as defined	in <link.h>. */static struct so_list *find_solib (so_list_ptr)     struct so_list *so_list_ptr;	/* Last lm or NULL for first one */{  struct so_list *so_list_next = NULL;  struct link_map *lm = NULL;  struct so_list *new;    if (so_list_ptr == NULL)    {      /* We are setting up for a new scan through the loaded images. */      if ((so_list_next = so_list_head) == NULL)	{	  /* We have not already read in the dynamic linking structures	     from the inferior, lookup the address of the base structure. */	  debug_base = locate_base ();	  if (debug_base > 0)	    {	      /* Read the base structure in and find the address of the first		 link map list member. */	      lm = first_link_map_member ();	    }	}    }  else    {      /* We have been called before, and are in the process of walking	 the shared library list.  Advance to the next shared object. */      if ((lm = LM_NEXT (so_list_ptr)) == NULL)	{	  /* We have hit the end of the list, so check to see if any were	     added, but be quiet if we can't read from the target any more. */	  int status = target_read_memory ((CORE_ADDR) so_list_ptr -> lmaddr,					   (char *) &(so_list_ptr -> lm),					   sizeof (struct link_map));	  if (status == 0)	    {	      lm = LM_NEXT (so_list_ptr);	    }	  else	    {	      lm = NULL;	    }	}      so_list_next = so_list_ptr -> next;    }  if ((so_list_next == NULL) && (lm != NULL))    {      /* Get next link map structure from inferior image and build a local	 abbreviated load_map structure */      new = (struct so_list *) xmalloc (sizeof (struct so_list));      memset ((char *) new, 0, sizeof (struct so_list));      new -> lmaddr = lm;      /* Add the new node as the next node in the list, or as the root	 node if this is the first one. */      if (so_list_ptr != NULL)	{	  so_list_ptr -> next = new;	}      else	{	  so_list_head = new;	}            so_list_next = new;      read_memory ((CORE_ADDR) lm, (char *) &(new -> lm),		   sizeof (struct link_map));      /* For the SVR4 version, there is one entry that has no name	 (for the inferior executable) since it is not a shared object. */      if (LM_NAME (new) != 0)	{	  if (!target_read_string((CORE_ADDR) LM_NAME (new), new -> so_name,		      MAX_PATH_SIZE - 1))	      error ("find_solib: Can't read pathname for load map\n");	  new -> so_name[MAX_PATH_SIZE - 1] = 0;	  solib_map_sections (new);	}          }  return (so_list_next);}/* A small stub to get us past the arg-passing pinhole of catch_errors.  */static intsymbol_add_stub (arg)     char *arg;{  register struct so_list *so = (struct so_list *) arg;	/* catch_errs bogon */    so -> objfile = symbol_file_add (so -> so_name, so -> from_tty,				   (unsigned int) so -> textsection -> addr,				   0, 0, 0);  return (1);}/*GLOBAL FUNCTION	solib_add -- add a shared library file to the symtab and section listSYNOPSIS	void solib_add (char *arg_string, int from_tty,			struct target_ops *target)DESCRIPTION*/voidsolib_add (arg_string, from_tty, target)     char *arg_string;     int from_tty;     struct target_ops *target;{	  register struct so_list *so = NULL;   	/* link map state variable */  char *re_err;  int count;  int old;    if ((re_err = re_comp (arg_string ? arg_string : ".")) != NULL)    {      error ("Invalid regexp: %s", re_err);    }    /* Getting new symbols may change our opinion about what is     frameless.  */  reinit_frame_cache ();    while ((so = find_solib (so)) != NULL)    {      if (so -> so_name[0] && re_exec (so -> so_name))	{	  if (so -> symbols_loaded)	    {	      if (from_tty)		{		  printf ("Symbols already loaded for %s\n", so -> so_name);		}	    }	  else	    {	      catch_errors (symbol_add_stub, (char *) so,			    "Error while reading shared library symbols:\n");	      	      special_symbol_handling (so);	      so -> symbols_loaded = 1;	      so -> from_tty = from_tty;	    }	}    }    /* Now add the shared library sections to the section table of the     specified target, if any.  */  if (target)    {      /* Count how many new section_table entries there are.  */      so = NULL;      count = 0;      while ((so = find_solib (so)) != NULL)	{	  if (so -> so_name[0])	    {	      count += so -> sections_end - so -> sections;	    }	}            if (count)	{	  /* Reallocate the target's section table including the new size.  */	  if (target -> to_sections)	    {	      old = target -> to_sections_end - target -> to_sections;	      target -> to_sections = (struct section_table *)		realloc ((char *)target -> to_sections,			 (sizeof (struct section_table)) * (count + old));	    }	  else	    {	      old = 0;	      target -> to_sections = (struct section_table *)		malloc ((sizeof (struct section_table)) * count);	    }	  target -> to_sections_end = target -> to_sections + (count + old);	  	  /* Add these section table entries to the target's table.  */	  while ((so = find_solib (so)) != NULL)	    {	      if (so -> so_name[0])		{		  count = so -> sections_end - so -> sections;		  memcpy ((char *) (target -> to_sections + old),			  so -> sections, 			  (sizeof (struct section_table)) * count);		  old += count;		}	    }	}    }}/*LOCAL FUNCTION	info_sharedlibrary_command -- code for "info sharedlibrary"SYNOPSIS	static void info_sharedlibrary_command ()DESCRIPTION	Walk through the shared library list and print information	about each attached library.*/static voidinfo_sharedlibrary_command (ignore, from_tty)     char *ignore;     int from_tty;{  register struct so_list *so = NULL;  	/* link map state variable */  int header_done = 0;    if (exec_bfd == NULL)    {      printf ("No exec file.\n");      return;    }  while ((so = find_solib (so)) != NULL)    {      if (so -> so_name[0])	{	  if (!header_done)	    {	      printf("%-12s%-12s%-12s%s\n", "From", "To", "Syms Read",		     "Shared Object Library");	      header_done++;	    }	  printf ("%-12s", local_hex_string_custom ((int) LM_ADDR (so), "08"));	  printf ("%-12s", local_hex_string_custom (so -> lmend, "08"));	  printf ("%-12s", so -> symbols_loaded ? "Yes" : "No");	  printf ("%s\n",  so -> so_name);	}    }  if (so_list_head == NULL)    {      printf ("No shared libraries loaded at this time.\n");	    }}/*GLOBAL FUNCTION	solib_address -- check to see if an address is in a shared libSYNOPSIS	int solib_address (CORE_ADDR address)DESCRIPTION	Provides a hook for other gdb routines to discover whether or	not a particular address is within the mapped address space of	a shared library.  Any address between the base mapping address	and the first address beyond the end of the last mapping, is	considered to be within the shared library address space, for

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -