mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
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:
committed by
Søren Sandmann Pedersen
parent
4050648b0e
commit
b54b0809b6
80
binfile.c
80
binfile.c
@ -23,9 +23,9 @@
|
||||
/* Most interesting code in this file is lifted from bfdutils.c
|
||||
* and process.c from Memprof,
|
||||
*/
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include "binfile.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
@ -33,7 +33,10 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "binfile.h"
|
||||
#include "elfparser.h"
|
||||
#include "process.h"
|
||||
|
||||
struct BinFile
|
||||
{
|
||||
@ -54,9 +57,11 @@ static ino_t
|
||||
read_inode (const char *filename)
|
||||
{
|
||||
struct stat statbuf;
|
||||
|
||||
|
||||
if (strcmp (filename, "[vdso]") == 0)
|
||||
return (ino_t)-1;
|
||||
|
||||
stat (filename, &statbuf);
|
||||
|
||||
return statbuf.st_ino;
|
||||
}
|
||||
|
||||
@ -84,7 +89,7 @@ separate_debug_file_exists (const char *name, guint32 crc)
|
||||
}
|
||||
|
||||
/* FIXME - not10: this should probably be detected by config.h -- find out what gdb does*/
|
||||
static const char *const debug_file_directory = "/usr/lib/debug";
|
||||
static const char *const debug_file_directory = DEBUGDIR;
|
||||
|
||||
static ElfParser *
|
||||
get_debug_file (ElfParser *elf,
|
||||
@ -131,6 +136,21 @@ get_debug_file (ElfParser *elf,
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
list_contains_name (GList *names, const char *name)
|
||||
{
|
||||
GList *list;
|
||||
for (list = names; list != NULL; list = list->next)
|
||||
{
|
||||
const char *n = list->data;
|
||||
|
||||
if (strcmp (n, name) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static ElfParser *
|
||||
find_separate_debug_file (ElfParser *elf,
|
||||
const char *filename)
|
||||
@ -138,29 +158,35 @@ find_separate_debug_file (ElfParser *elf,
|
||||
ElfParser *debug;
|
||||
char *debug_name = NULL;
|
||||
char *fname;
|
||||
GList *seen_names = NULL;
|
||||
|
||||
fname = g_strdup (filename);
|
||||
|
||||
/* FIXME: there is an infinite loop if there are cycles in
|
||||
* the debug_link graph
|
||||
*/
|
||||
do
|
||||
{
|
||||
if (list_contains_name (seen_names, fname))
|
||||
{
|
||||
/* cycle detected, just return the original elf file itself */
|
||||
break;
|
||||
}
|
||||
|
||||
debug = get_debug_file (elf, fname, &debug_name);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
elf_parser_free (elf);
|
||||
elf = debug;
|
||||
|
||||
g_free (fname);
|
||||
|
||||
seen_names = g_list_prepend (seen_names, fname);
|
||||
fname = debug_name;
|
||||
}
|
||||
}
|
||||
while (debug);
|
||||
|
||||
g_free (fname);
|
||||
|
||||
g_list_foreach (seen_names, (GFunc)g_free, NULL);
|
||||
g_list_free (seen_names);
|
||||
|
||||
return elf;
|
||||
}
|
||||
|
||||
@ -184,15 +210,38 @@ bin_file_new (const char *filename)
|
||||
else
|
||||
{
|
||||
bf = g_new0 (BinFile, 1);
|
||||
bf->elf = elf_parser_new (filename, NULL);
|
||||
|
||||
if (strcmp (filename, "[vdso]") == 0)
|
||||
{
|
||||
gsize length;
|
||||
const guint8 *vdso_bytes;
|
||||
|
||||
vdso_bytes = process_get_vdso_bytes (&length);
|
||||
if (vdso_bytes)
|
||||
{
|
||||
bf->elf = elf_parser_new_from_data (vdso_bytes, length);
|
||||
#if 0
|
||||
g_print ("got vdso elf: %p (%d)\n", bf->elf, length);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
bf->elf = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bf->elf = elf_parser_new (filename, NULL);
|
||||
}
|
||||
|
||||
/* We need the text offset of the actual binary, not the
|
||||
* (potential) debug binary
|
||||
*/
|
||||
if (bf->elf)
|
||||
{
|
||||
bf->text_offset = elf_parser_get_text_offset (bf->elf);
|
||||
|
||||
#if 0
|
||||
g_print ("text offset: %d\n", bf->text_offset);
|
||||
#endif
|
||||
|
||||
bf->elf = find_separate_debug_file (bf->elf, filename);
|
||||
}
|
||||
|
||||
@ -200,7 +249,7 @@ bin_file_new (const char *filename)
|
||||
bf->filename = g_strdup (filename);
|
||||
bf->undefined_name = g_strdup_printf ("In file %s", filename);
|
||||
bf->ref_count = 1;
|
||||
|
||||
|
||||
g_hash_table_insert (bin_files, bf->filename, bf);
|
||||
}
|
||||
|
||||
@ -229,12 +278,15 @@ bin_file_lookup_symbol (BinFile *bin_file,
|
||||
{
|
||||
if (bin_file->elf)
|
||||
{
|
||||
#if 0
|
||||
g_print ("bin file lookup lookup %d\n", address);
|
||||
#endif
|
||||
address -= bin_file->text_offset;
|
||||
|
||||
const ElfSym *sym = elf_parser_lookup_symbol (bin_file->elf, address);
|
||||
|
||||
#if 0
|
||||
g_print ("lookup in %s\n", bin_file->filename);
|
||||
g_print ("lookup %d in %s\n", address, bin_file->filename);
|
||||
#endif
|
||||
|
||||
if (sym)
|
||||
|
||||
Reference in New Issue
Block a user