*** empty log message ***

This commit is contained in:
Søren Sandmann Pedersen
2004-11-04 15:25:39 +00:00
parent e16af9c730
commit 1fa465fb26
4 changed files with 101 additions and 24 deletions

View File

@ -394,7 +394,9 @@ bin_file_lookup_symbol (BinFile *bf,
data = bf->symbols; data = bf->symbols;
#if 0
g_print ("looking up %p in %s ", address, bf->filename); g_print ("looking up %p in %s ", address, bf->filename);
#endif
if (address < data[last].address) if (address < data[last].address)
{ {
@ -418,7 +420,9 @@ bin_file_lookup_symbol (BinFile *bf,
result = &data[last]; result = &data[last];
} }
#if 0
g_print ("-> %s\n", result->name); g_print ("-> %s\n", result->name);
#endif
/* If the name is "call_gmon_start", the file probably doesn't /* If the name is "call_gmon_start", the file probably doesn't
* have any other symbols * have any other symbols

View File

@ -22,7 +22,7 @@ struct Map
char * filename; char * filename;
gulong start; gulong start;
gulong end; gulong end;
gulong offset; gulong offset;
gboolean do_offset; gboolean do_offset;
BinFile * bin_file; BinFile * bin_file;
@ -34,6 +34,8 @@ struct Process
GList *maps; GList *maps;
GList *bad_pages; GList *bad_pages;
int pid;
}; };
static void static void
@ -68,15 +70,6 @@ should_offset (const char *filename, int pid)
return result; return result;
} }
static gboolean
check_do_offset (const Map *map, int pid)
{
if (map->filename)
return should_offset (map->filename, pid);
else
return TRUE;
}
static GList * static GList *
read_maps (int pid) read_maps (int pid)
{ {
@ -99,21 +92,25 @@ read_maps (int pid)
guint start; guint start;
guint end; guint end;
guint offset; guint offset;
#if 0
g_print ("buffer: %s\n", buffer);
#endif
count = sscanf ( count = sscanf (
buffer, "%x-%x %*15s %x %*u:%*u %*u %255s", buffer, "%x-%x %*15s %x %*x:%*x %*u %255s",
&start, &end, &offset, file); &start, &end, &offset, file);
if (count == 4) if (count == 4)
{ {
Map *map; Map *map;
map = g_new (Map, 1); map = g_new (Map, 1);
map->filename = g_strdup (file); map->filename = g_strdup (file);
map->start = start; map->start = start;
map->end = end; map->end = end;
map->offset = offset; //check_do_offset (map, pid); map->offset = offset;
map->bin_file = NULL; map->bin_file = NULL;
@ -137,6 +134,7 @@ create_process (const char *cmdline, int pid)
p->cmdline = g_strdup_printf ("[%s]", cmdline); p->cmdline = g_strdup_printf ("[%s]", cmdline);
p->bad_pages = NULL; p->bad_pages = NULL;
p->maps = NULL; p->maps = NULL;
p->pid = pid;
g_assert (!g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid))); g_assert (!g_hash_table_lookup (processes_by_pid, GINT_TO_POINTER (pid)));
g_assert (!g_hash_table_lookup (processes_by_cmdline, cmdline)); g_assert (!g_hash_table_lookup (processes_by_cmdline, cmdline));
@ -269,7 +267,7 @@ process_lookup_symbol (Process *process, gulong address)
g_free (undefined.name); g_free (undefined.name);
undefined.name = g_strdup_printf ("??? (%s)", process->cmdline); undefined.name = g_strdup_printf ("??? (%s)", process->cmdline);
undefined.address = 0xBABE0001; undefined.address = 0xBABE0001;
return &undefined; return &undefined;
} }
@ -282,17 +280,22 @@ process_lookup_symbol (Process *process, gulong address)
if (!map->bin_file) if (!map->bin_file)
map->bin_file = bin_file_new (map->filename); map->bin_file = bin_file_new (map->filename);
#if 0
/* FIXME - this seems to work with prelinked binaries, but is /* FIXME - this seems to work with prelinked binaries, but is
* it correct? IE., will normal binaries always have a preferred_addres of 0? * it correct? IE., will normal binaries always have a preferred_addres of 0?
*/ */
/* address = address - map->start + map->offset + bin_file_get_load_address (map->bin_file); */ address = address - map->start + map->offset + bin_file_get_load_address (map->bin_file);
/* address -= map->start; */ address -= map->start;
/* address += map->offset; */ address += map->offset;
/* address += bin_file_get_load_address (map->bin_file); */ address += bin_file_get_load_address (map->bin_file);
#endif
/* g_print ("%s: start: %p, load: %p\n", */ /* g_print ("%s: start: %p, load: %p\n", */
/* map->filename, map->start, bin_file_get_load_address (map->bin_file)); */ /* map->filename, map->start, bin_file_get_load_address (map->bin_file)); */
if (should_offset (map->filename, process->pid))
address -= map->start;
result = bin_file_lookup_symbol (map->bin_file, address); result = bin_file_lookup_symbol (map->bin_file, address);
/* g_print ("(%x) %x %x name; %s\n", address, map->start, map->offset, result->name); */ /* g_print ("(%x) %x %x name; %s\n", address, map->start, map->offset, result->name); */

View File

@ -7,14 +7,13 @@
#include <asm/atomic.h> #include <asm/atomic.h>
#include <linux/kernel.h> /* Needed for KERN_ALERT */ #include <linux/kernel.h> /* Needed for KERN_ALERT */
#include <linux/module.h> /* Needed by all modules */ #include <linux/module.h> /* Needed by all modules */
#ifdef KERNEL24
# include <linux/tqueue.h>
#endif
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/pagemap.h>
#include "sysprof-module.h" #include "sysprof-module.h"
@ -79,13 +78,76 @@ init_userspace_reader (userspace_reader *reader,
reader->page = NULL; reader->page = NULL;
} }
/* Access another process' address space.
* Source/target buffer must be kernel space,
* Do not walk the page table directly, use get_user_pages
*/
static int x_access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
{
struct mm_struct *mm;
struct vm_area_struct *vma;
struct page *page;
void *old_buf = buf;
mm = tsk->mm;
if (!mm)
return 0;
down_read(&mm->mmap_sem);
/* ignore errors, just check how much was sucessfully transfered */
while (len) {
int bytes, ret, offset;
void *maddr;
ret = get_user_pages(tsk, mm, addr, 1,
write, 1, &page, &vma);
if (ret <= 0)
break;
bytes = len;
offset = addr & (PAGE_SIZE-1);
if (bytes > PAGE_SIZE-offset)
bytes = PAGE_SIZE-offset;
flush_cache_page(vma, addr);
maddr = kmap(page);
if (write) {
copy_to_user_page(vma, page, addr,
maddr + offset, buf, bytes);
set_page_dirty_lock(page);
} else {
copy_from_user_page(vma, page, addr,
buf, maddr + offset, bytes);
}
kunmap(page);
page_cache_release(page);
len -= bytes;
buf += bytes;
addr += bytes;
}
up_read(&mm->mmap_sem);
return buf - old_buf;
}
static int static int
read_user_space (userspace_reader *reader, read_user_space (userspace_reader *reader,
unsigned long address, unsigned long address,
unsigned long *result) unsigned long *result)
{ {
#if 0
unsigned long user_page = (address & PAGE_MASK); unsigned long user_page = (address & PAGE_MASK);
int res; int res;
#endif
return x_access_process_vm(reader->task, address, result, 4, 0);
}
#if 0
struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
if (user_page == 0) if (user_page == 0)
return 0; return 0;
@ -93,19 +155,24 @@ read_user_space (userspace_reader *reader,
if (!reader->user_page || user_page != reader->user_page) { if (!reader->user_page || user_page != reader->user_page) {
int found; int found;
struct page *page; struct page *page;
pte_t pte;
found = get_user_pages (reader->task, reader->task->mm, user_page, found = get_user_pages (reader->task, reader->task->mm,
1, 0, 0, &page, NULL); user_page, 1, 0, 0, &page, NULL);
if (!found) if (!found)
return 0; return 0;
if (!pte_present (page))
return 0;
if (reader->user_page) if (reader->user_page)
kunmap (reader->page); kunmap (reader->page);
reader->user_page = user_page;
reader->kernel_page = (unsigned long)kmap (page); reader->kernel_page = (unsigned long)kmap (page);
reader->user_page = user_page;
reader->page = page; reader->page = page;
} }
if (get_user (res, (int *)(reader->kernel_page + (address - user_page))) != 0) if (get_user (res, (int *)(reader->kernel_page + (address - user_page))) != 0)
@ -115,6 +182,7 @@ read_user_space (userspace_reader *reader,
return 1; return 1;
} }
#endif
static void static void
done_userspace_reader (userspace_reader *reader) done_userspace_reader (userspace_reader *reader)

View File

@ -110,10 +110,12 @@ on_read (gpointer data)
rd = read (app->input_fd, &trace, sizeof (trace)); rd = read (app->input_fd, &trace, sizeof (trace));
#if 0
g_print ("pid: %d\n", trace.pid); g_print ("pid: %d\n", trace.pid);
for (i=0; i < trace.n_addresses; ++i) for (i=0; i < trace.n_addresses; ++i)
g_print ("rd: %08x\n", trace.addresses[i]); g_print ("rd: %08x\n", trace.addresses[i]);
g_print ("-=-\n"); g_print ("-=-\n");
#endif
if (rd > 0 && app->profiling && !app->generating_profile) if (rd > 0 && app->profiling && !app->generating_profile)
{ {