New function.

2006-10-09  Soren Sandmann  <ssp@localhost.localdomain>

	* process.c (process_get_vdso_bytes): New function.

	* elfparser.c (parser_new_from_data): export this function as
	elf_parser_new_from_data().

	* binfile.c (read_inode): Don't stat if filename is
	'[vdso]'. Instead just return -1;
	(bin_file_new): Use elf_parser_new_from_data() when the file is
	[vdso].

	* process.c (read_maps): Change the offset of the vdso map to 0
	and the inode to -1.

	* elfparser.c (elf_parser_lookup_symbol): Remove unused 'size'
	variable.

	* binfile.c (find_separate_debug_file): Deal with cycles in the
	debuglink graph.

	* configure.ac: Set version to 1.1.0. Print warning about HEAD.
This commit is contained in:
Soren Sandmann
2006-10-09 21:32:24 +00:00
committed by Søren Sandmann Pedersen
parent 4050648b0e
commit b54b0809b6
8 changed files with 190 additions and 55 deletions

107
process.c
View File

@ -25,6 +25,7 @@
#include <sys/stat.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include "process.h"
#include "binfile.h"
@ -115,10 +116,24 @@ read_maps (int pid)
map->start = start;
map->end = end;
map->offset = offset;
if (strcmp (map->filename, "[vdso]") == 0)
{
/* The kernel reports offset the same as the
* mapping address, which doesn't make much sense
* to me. So just zero it out here
*/
#if 0
g_print ("fixing up\n");
#endif
map->offset = 0;
map->inode = -1;
}
else
{
map->offset = offset;
map->inode = inode;
}
map->inode = inode;
map->bin_file = NULL;
result = g_list_prepend (result, map);
@ -136,6 +151,61 @@ read_maps (int pid)
return result;
}
static void
free_maps (GList *maps)
{
GList *list;
for (list = maps; list != NULL; list = list->next)
{
Map *map = list->data;
if (map->filename)
g_free (map->filename);
if (map->bin_file)
bin_file_free (map->bin_file);
g_free (map);
}
g_list_free (maps);
}
const guint8 *
process_get_vdso_bytes (gsize *length)
{
static gboolean has_data;
static const guint8 *bytes = NULL;
static gsize n_bytes = 0;
if (!has_data)
{
GList *maps = read_maps (getpid());
GList *list;
for (list = maps; list != NULL; list = list->next)
{
Map *map = list->data;
if (strcmp (map->filename, "[vdso]") == 0)
{
bytes = (guint8 *)map->start;
n_bytes = map->end - map->start;
}
}
has_data = TRUE;
free_maps (maps);
}
if (length)
*length = n_bytes;
g_print ("the vdso is %p\n", bytes);
return bytes;
}
static Process *
create_process (const char *cmdline, int pid)
@ -182,28 +252,6 @@ process_locate_map (Process *process, gulong addr)
return NULL;
}
static void
process_free_maps (Process *process)
{
GList *list;
for (list = process->maps; list != NULL; list = list->next)
{
Map *map = list->data;
if (map->filename)
g_free (map->filename);
if (map->bin_file)
bin_file_free (map->bin_file);
g_free (map);
}
g_list_free (process->maps);
}
static void
free_process (gpointer key, gpointer value, gpointer data)
{
@ -218,7 +266,7 @@ free_process (gpointer key, gpointer value, gpointer data)
#if 0
process->cmdline = "You are using free()'d memory";
#endif
process_free_maps (process);
free_maps (process->maps);
g_list_free (process->bad_pages);
g_free (cmdline);
@ -265,7 +313,7 @@ process_ensure_map (Process *process, int pid, gulong addr)
/* a map containing addr was not found */
if (process->maps)
process_free_maps (process);
free_maps (process->maps);
process->maps = read_maps (pid);
@ -600,7 +648,7 @@ process_lookup_symbol (Process *process, gulong address)
#endif
#if 0
if (strcmp (map->filename, "/home/ssp/sysprof/sysprof") == 0)
if (strcmp (map->filename, "[vdso]") == 0)
{
g_print ("address after: %lx\n", address);
}
@ -618,7 +666,8 @@ process_lookup_symbol (Process *process, gulong address)
* file has changed since the process started. Just return
* the undefined symbol in that case.
*/
g_print ("warning: %s has wrong inode (%d, should be %d)\n",
map->filename, map->inode, bin_file_get_inode (map->bin_file));
address = 0x0;
}