diff -uarN oprofile.orig/daemon/Makefile.am oprofile.mod/daemon/Makefile.am
--- oprofile.orig/daemon/Makefile.am	2004-02-22 22:57:30.000000000 -0700
+++ oprofile.mod/daemon/Makefile.am	2004-11-11 16:16:35.000000000 -0700
@@ -21,9 +21,13 @@
 	opd_mangling.c \
 	opd_mangling.h \
 	opd_perfmon.h \
-	opd_perfmon.c
+	opd_perfmon.c \
+	opd_ipc.c \
+	opd_ipc.h \
+	opd_ipc_commands.c \
+	opd_ipc_commands.h
 
-LIBS=@POPT_LIBS@ @LIBERTY_LIBS@
+LIBS=@POPT_LIBS@ @LIBERTY_LIBS@ -lpthread
 
 AM_CPPFLAGS = \
 	-I ${top_srcdir}/libabi \
diff -uarN oprofile.orig/daemon/init.c oprofile.mod/daemon/init.c
--- oprofile.orig/daemon/init.c	2004-01-29 13:00:26.000000000 -0700
+++ oprofile.mod/daemon/init.c	2004-11-11 16:16:35.000000000 -0700
@@ -18,6 +18,8 @@
 #include "opd_trans.h"
 #include "opd_perfmon.h"
 #include "opd_printf.h"
+#include "opd_ipc.h"
+#include "opd_ipc_commands.h"
 
 #include "op_version.h"
 #include "op_config.h"
@@ -209,6 +211,7 @@
 
 static void opd_sigterm(void)
 {
+	opd_ipc_pipe_clean();
 	opd_print_stats();
 	printf("oprofiled stopped %s", op_get_time());
 	exit(EXIT_FAILURE);
@@ -230,6 +233,7 @@
 	sbuf = xmalloc(s_buf_bytesize);
 
 	opd_reread_module_info();
+	opd_ipc_read_mapping_commands();
 
 	for (i = 0; i < OPD_MAX_STATS; i++)
 		opd_stats[i] = 0;
@@ -259,6 +263,7 @@
 
 static void opd_26_exit(void)
 {
+	opd_ipc_pipe_clean();
 	opd_print_stats();
 	printf("oprofiled stopped %s", op_get_time());
 
diff -uarN oprofile.orig/daemon/liblegacy/init.c oprofile.mod/daemon/liblegacy/init.c
--- oprofile.orig/daemon/liblegacy/init.c	2004-01-29 13:00:26.000000000 -0700
+++ oprofile.mod/daemon/liblegacy/init.c	2004-11-11 16:16:35.000000000 -0700
@@ -19,6 +19,7 @@
 #include "opd_parse_proc.h"
 #include "opd_kernel.h"
 #include "opd_printf.h"
+#include "opd_ipc.h"
 #include "oprofiled.h"
 
 #include "op_sample_file.h"
@@ -321,6 +322,7 @@
 
 static void opd_sigterm(void)
 {
+	opd_ipc_pipe_clean();
 	opd_print_24_stats();
 	printf("oprofiled stopped %s", op_get_time());
 	exit(EXIT_FAILURE);
@@ -373,6 +375,7 @@
 
 static void opd_24_exit(void)
 {
+	opd_ipc_pipe_clean();
 	opd_print_24_stats();
 	printf("oprofiled stopped %s", op_get_time());
 
diff -uarN oprofile.orig/daemon/liblegacy/opd_kernel.c oprofile.mod/daemon/liblegacy/opd_kernel.c
--- oprofile.orig/daemon/liblegacy/opd_kernel.c	2004-01-29 13:00:26.000000000 -0700
+++ oprofile.mod/daemon/liblegacy/opd_kernel.c	2004-11-11 16:16:35.000000000 -0700
@@ -16,6 +16,7 @@
 #include "opd_printf.h"
 #include "opd_24_stats.h"
 #include "oprofiled.h"
+#include "opd_ipc_commands.h"
 
 #include "op_fileio.h"
 #include "op_config_24.h"
@@ -26,14 +27,6 @@
 #include <stdlib.h>
 #include <errno.h>
 
-/* kernel module */
-struct opd_module {
-	char * name;
-	struct opd_image * image;
-	unsigned long start;
-	unsigned long end;
-	struct list_head module_list;
-};
 
 static struct opd_image * kernel_image;
 
@@ -75,8 +68,8 @@
  * @param start start address
  * @param end end address
  */
-static struct opd_module *
-opd_create_module(char * name, unsigned long start, unsigned long end)
+struct opd_module *
+opd_create_module_24(char * name, unsigned long start, unsigned long end)
 {
 	struct opd_module * module = xmalloc(sizeof(struct opd_module));
 
@@ -85,14 +78,16 @@
 	module->start = start;
 	module->end = end;
 	list_add(&module->module_list, &opd_modules);
-
+	
+	printf("legacy: Added a module for '%s', start=0x%lx, end=0x%lx\n",
+	       module->name, module->start, module->end);
 	return module;
 }
 
 
 /**
- * opd_find_module_by_name - find a module by name, ccreating a new once if
- * search fail
+ * opd_find_module_by_name - find a module by name, creating a new one if
+ * the search fails
  * @param name module name
  */
 static struct opd_module * opd_find_module_by_name(char * name)
@@ -106,7 +101,7 @@
 			return module;
 	}
 
-	return opd_create_module(name, 0, 0);
+	return opd_create_module_24(name, 0, 0);
 }
 
 
@@ -297,7 +292,7 @@
 		if (!query_module(name, QM_INFO, &info, sizeof(info), &ret)) {
 			if (eip >= info.addr && eip < info.addr + info.size) {
 				verbprintf(vmodule, "Sample from unprofilable module %s\n", name);
-				opd_create_module(name, info.addr, info.addr + info.size);
+				opd_create_module_24(name, info.addr, info.addr + info.size);
 				break;
 			}
 		}
@@ -325,6 +320,8 @@
 
 	list_for_each(pos, &opd_modules) {
 		module = list_entry(pos, struct opd_module, module_list);
+		printf("legacy: Looking for eip 0x%lx, within '%s', start=0x%lx, end=0x%lx\n",
+		       eip, module->name, module->start, module->end);
 		if (module->start <= eip && module->end > eip)
 			return module;
 	}
@@ -353,16 +350,21 @@
 {
 	struct opd_module * module;
 
+	printf("opd_handle_module_sample: eip=0x%lx, counter=%d\n", eip, counter);
+
 	module = opd_find_module_by_eip(eip);
 	if (!module) {
+	  printf("opd_handle_module_sample: -1 module not found\n");
 		/* not found in known modules, re-read our info and retry */
 		opd_clear_module_info();
 		opd_get_module_info();
+		opd_ipc_read_mapping_commands();
 
 		module = opd_find_module_by_eip(eip);
 	}
 
 	if (module) {
+	  printf("opd_handle_module_sample: -2 processing\n");
 		if (module->image != NULL) {
 			opd_24_stats[OPD_MODULE]++;
 			opd_put_image_sample(module->image,
@@ -373,6 +375,7 @@
 				   module->name);
 		}
 	} else {
+	  printf("opd_handle_module_sample: -4 dropping\n");
 		opd_drop_module_sample(eip);
 	}
 }
@@ -427,6 +430,7 @@
 		/* not found in known modules, re-read our info and retry */
 		opd_clear_module_info();
 		opd_get_module_info();
+		opd_ipc_read_mapping_commands();
 
 		module = opd_find_module_by_eip(eip);
 	}
diff -uarN oprofile.orig/daemon/liblegacy/opd_kernel.h oprofile.mod/daemon/liblegacy/opd_kernel.h
--- oprofile.orig/daemon/liblegacy/opd_kernel.h	2003-10-27 16:27:19.000000000 -0700
+++ oprofile.mod/daemon/liblegacy/opd_kernel.h	2004-11-11 16:16:35.000000000 -0700
@@ -12,10 +12,20 @@
 #ifndef OPD_KERNEL_H
 #define OPD_KERNEL_H
 
+#include "op_list.h"
 #include "op_types.h"
 
 struct opd_proc;
 
+/* kernel module */
+struct opd_module {
+	char * name;
+	struct opd_image * image;
+	unsigned long start;
+	unsigned long end;
+	struct list_head module_list;
+};
+
 /**
  * opd_init_kernel_image - initialise the kernel image
  */
@@ -26,6 +36,9 @@
  */
 void opd_parse_kernel_range(char const * arg);
 
+/** allocate and initialise a module description */
+struct opd_module * opd_create_module_24(char * name, unsigned long start, unsigned long end);
+
 /**
  * opd_clear_module_info - clear kernel module information
  *
diff -uarN oprofile.orig/daemon/opd_ipc.c oprofile.mod/daemon/opd_ipc.c
--- oprofile.orig/daemon/opd_ipc.c	1969-12-31 17:00:00.000000000 -0700
+++ oprofile.mod/daemon/opd_ipc.c	2004-11-11 16:16:35.000000000 -0700
@@ -0,0 +1,172 @@
+/**
+ * @file opd_ipc.c
+ *
+ * IPC interface with daemon
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Kristis Makris
+ * @author John Levon
+ */
+
+#include "opd_ipc.h"
+#include "opd_ipc_commands.h"
+
+#include "op_fileio.h"
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+
+
+/** @brief Used for IPC communication with the daemon */
+int ipc_pipe_fd;
+
+/** @brief Thread Id of IPC control commands thread. */
+pthread_t ipc_tid;
+
+
+/** @brief initializes IPC using a pipe */
+void opd_ipc_pipe_setup(void)
+{
+  FILE *fp;
+
+  printf("Using IPC file " OPD_IPC_PIPE_NAME "\n");
+
+  /* Wipe the mappings file clean */
+  fp = op_try_open_file(OPD_IPC_COMMANDS_FILE, "w+");
+  if (!fp) {
+    printf("oprofiled: " OPD_IPC_COMMANDS_FILE " could not be wiped clean\n");
+    exit(EXIT_FAILURE);
+  } else {
+    op_close_file(fp);
+  }
+
+  opd_ipc_pipe_start_read_thread();
+}
+
+
+/** @brief Cleans up IPC using a pipe */
+void opd_ipc_pipe_clean(void)
+{
+  opd_ipc_pipe_stop_read_thread();
+  opd_ipc_pipe_close();
+  opd_ipc_pipe_remove();
+}
+
+
+/** @brief Creates a named pipe for IPC with the daemon */
+void opd_ipc_pipe_create(void)
+{
+  int mkfifo_retval;
+
+  mkfifo_retval = mkfifo(OPD_IPC_PIPE_NAME, 0);
+  
+  if (mkfifo_retval != 0 &&
+      errno != EEXIST) {
+    /* Stop if this pipe file could not be created, but not if it
+       exists already. */
+    perror("oprofiled: couldn't create IPC pipe " OPD_IPC_PIPE_NAME);
+    exit(EXIT_FAILURE);
+  }
+}
+
+
+/** *@brief Opens the daemon IPC pipe */
+void opd_ipc_pipe_open(void)
+{
+  ipc_pipe_fd = open(OPD_IPC_PIPE_NAME, O_RDONLY);
+  if (ipc_pipe_fd == -1) {
+    perror("oprofiled: couldn't open IPC pipe " OPD_IPC_PIPE_NAME);
+    exit(EXIT_FAILURE);
+  }
+}
+
+
+/** @brief Reads a run-time control command through the IPC communication pipe. */
+void opd_ipc_pipe_read(void)
+{
+  
+}
+
+
+/** @brief Closes the daemon IPC pipe */
+void opd_ipc_pipe_close(void)
+{
+  if (close(ipc_pipe_fd) != 0) {
+    perror("oprofiled: couldn't close IPC pipe " OPD_IPC_PIPE_NAME);
+    exit(EXIT_FAILURE);
+  }
+}
+
+
+/** @brief Removes the pipe used for IPC with the daemon */
+void opd_ipc_pipe_remove(void)
+{
+  if (remove(OPD_IPC_PIPE_NAME) != 0) {
+    perror("oprofiled: couldn't remove IPC pipe " OPD_IPC_PIPE_NAME);
+    exit(EXIT_FAILURE);
+  }
+
+}
+
+
+/** @brief Starts the thread used for IPC with the daemon. */
+void opd_ipc_pipe_start_read_thread(void)
+{
+  pthread_create(&ipc_tid, NULL, opd_ipc_pipe_read_thread, NULL);
+}
+
+
+/** @brief Stops the thread used for IPC with the daemon. */
+void opd_ipc_pipe_stop_read_thread(void)
+{
+  printf("Stopping IPC read thread\n");
+  pthread_exit(EXIT_SUCCESS);
+}
+
+
+/** @brief Main workhorse of thread that waits for IPC commands
+ *
+ * Data are send to the pipe in a text format to facilitate creation
+ * of scripts that issue daemon control commands. The data are parsed
+ * out and translated to their respective control commands.
+ *
+ * The following are some commands accepted by the daemon:
+ *  add_mapping <module_name> <module_start_address> <module_end_address>
+ *
+ * @param args Is required by pthread_create but is not used.
+ */
+void * opd_ipc_pipe_read_thread(void * args __attribute__ ((unused)))
+{
+  char ipc_command_buffer[OPD_IPC_COMMAND_BUFFER_SIZE];
+
+  opd_ipc_pipe_create();
+
+  while(1) {
+    int read_retval;
+
+    /* Opening and closing the pipe each time guarantees that the
+       read() call blocks and the thread sleeps. */
+    opd_ipc_pipe_open();
+    read_retval = read(ipc_pipe_fd, &ipc_command_buffer, OPD_IPC_COMMAND_BUFFER_SIZE);
+    opd_ipc_pipe_close();
+
+    if (read_retval == -1) {
+      perror("oprofiled: couldn't read data from IPC pipe " OPD_IPC_PIPE_NAME);
+    } else if (read_retval == 0) {
+      /* This is the end of file. No more data to read. */
+    } else {
+      /* Data were read. They arrived in a text-based format. Parse
+	 the data out. */
+      opd_ipc_process_commands((char *)&ipc_command_buffer);
+    }
+  }
+}
+
diff -uarN oprofile.orig/daemon/opd_ipc.h oprofile.mod/daemon/opd_ipc.h
--- oprofile.orig/daemon/opd_ipc.h	1969-12-31 17:00:00.000000000 -0700
+++ oprofile.mod/daemon/opd_ipc.h	2004-11-11 16:16:35.000000000 -0700
@@ -0,0 +1,39 @@
+/**
+ * @file opd_ipc.h
+ *
+ * IPC interface with daemon
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Kristis Makris
+ * @author John Levon
+ */
+
+
+#ifndef OPD_IPC_H
+#define OPD_IPC_H
+
+#include "op_config.h"
+
+
+/** Name of named pipe used for IPC with the daemon */
+#define OPD_IPC_PIPE_NAME OP_BASE_DIR "oprofiled.ipc"
+
+/** Maximum size of a collection of commands send to the daemon
+    through a pipe in text-based format */
+#define OPD_IPC_COMMAND_BUFFER_SIZE (1024 * 32)
+
+void opd_ipc_pipe_setup(void);
+void opd_ipc_pipe_clean(void);
+void opd_ipc_pipe_create(void);
+void opd_ipc_pipe_open(void);
+void opd_ipc_pipe_read(void);
+void opd_ipc_pipe_close(void);
+void opd_ipc_pipe_remove(void);
+void opd_ipc_pipe_start_read_thread(void);
+void opd_ipc_pipe_stop_read_thread(void);
+void * opd_ipc_pipe_read_thread(void *args);
+
+
+#endif /* OPD_IPC_H */
diff -uarN oprofile.orig/daemon/opd_ipc_commands.c oprofile.mod/daemon/opd_ipc_commands.c
--- oprofile.orig/daemon/opd_ipc_commands.c	1969-12-31 17:00:00.000000000 -0700
+++ oprofile.mod/daemon/opd_ipc_commands.c	2004-11-11 16:16:35.000000000 -0700
@@ -0,0 +1,169 @@
+/**
+ * @file opd_ipc_commands.c
+ *
+ * Process IPC control commands
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Kristis Makris
+ * @author John Levon
+ */
+
+#include "opd_ipc_commands.h"
+#include "liblegacy/opd_kernel.h"
+#include "liblegacy/opd_image.h"
+#include "opd_ipc.h"
+
+
+#include "op_types.h"
+#include "op_fileio.h"
+#include "op_config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/** @brief Processes a single daemon control command. */
+void opd_ipc_process_commands(char *commands)
+{
+  /*
+  char *line;
+  char *scratch_buffer = (char *)malloc(strlen(commands));
+
+  line = strtok_r(commands, "\n", &scratch_buffer);
+  while (line != NULL) {
+    opd_ipc_process_command(line);
+    strtok_r(NULL, "\n", &scratch_buffer);
+  }
+  */
+  opd_ipc_process_command(commands);
+}
+
+
+/** @brief Processes a single daemon control command. */
+void opd_ipc_process_command(char *command)
+{
+  char *token;
+  /* Make a copy because strtok modifies the original command. */
+  char *command_copy = strdup(command);
+
+  token = strtok(command, OPD_IPC_COMMANDS_DELIMITERS);
+  
+  /* A junk command might have been received */
+  if (token == NULL) {
+    printf("oprofiled: received junk IPC command '%s'\n", command);
+    return;
+  }
+
+  if (strcmp(token,OPD_IPC_COMMAND_ADD_MAPPING) == 0) {
+    opd_ipc_process_command_add_mapping(command_copy);
+    free(command_copy);
+  }
+}
+
+
+/** @brief Processes a daemon control command to add a module
+    mapping.
+
+    The format of this command is:
+
+    add_mapping my_jitted_code_module_name 0xstart_address 0xend_address
+ */
+void opd_ipc_process_command_add_mapping(const char *original_command)
+{
+  char *module_name;
+  char *module_start_address;
+  char *module_end_address;
+  vma_t start_address;
+  vma_t end_address;
+  struct opd_module *opd_module;
+
+  /* Parse the module name */
+  module_name = strtok(NULL, OPD_IPC_COMMANDS_DELIMITERS);
+  if (module_name == NULL) {
+    printf("oprofiled: " OPD_IPC_COMMAND_ADD_MAPPING ": No module name provided\n");
+    return;
+  }
+  
+  /* Parse the module start address */
+  module_start_address = strtok(NULL, OPD_IPC_COMMANDS_DELIMITERS);
+  if (module_start_address == NULL) {
+    printf("oprofiled: " OPD_IPC_COMMAND_ADD_MAPPING ": No module start address provided\n");
+    return;
+  }
+  if (sscanf(module_start_address, "0x%llx", &start_address) != 1) {
+    printf("oprofiled: " OPD_IPC_COMMAND_ADD_MAPPING ": Module start address could not be parsed\n");
+    return;
+  }
+
+  /* Parse the module end address */
+  module_end_address = strtok(NULL, OPD_IPC_COMMANDS_DELIMITERS);
+  if (module_end_address == NULL) {
+    printf("oprofiled: " OPD_IPC_COMMAND_ADD_MAPPING ": No module end address provided\n");
+    return;
+  }
+  if (sscanf(module_end_address, "0x%llx", &end_address) != 1) {
+    printf("oprofiled: " OPD_IPC_COMMAND_ADD_MAPPING ": Module end address could not be parsed\n");
+    return;
+  }
+
+  /* Add the module mapping */
+  opd_ipc_save_mapping_command(original_command);
+  opd_module = opd_create_module_24(module_name, start_address, end_address);
+  opd_module->image = opd_get_kernel_image(module_name, NULL, 0, 0);
+  opd_module->image->ref_count++;
+  printf("oprofiled: added module mapping %s:0x%llx:0x%llx\n",
+	 module_name, start_address, end_address);
+}
+
+
+/** @brief Saves a mapping command for later requery */
+void opd_ipc_save_mapping_command(const char *original_command)
+{
+  FILE *fp;
+
+  fp = op_try_open_file(OPD_IPC_COMMANDS_FILE, "a+");
+
+  if (!fp) {
+    printf("oprofiled: " OPD_IPC_COMMANDS_FILE " cannot be opened for append\n");
+    return;
+  } else {
+    op_write_file(fp, original_command, strlen(original_command));
+    op_close_file(fp);
+  }
+}
+
+
+/** @brief Rereads all mapping commands that were dynamically issued
+    to the daemon */
+void opd_ipc_read_mapping_commands()
+{
+  FILE *fp;
+
+  printf("opd_ipc_read_mapping_commands - in\n");
+  fp = op_try_open_file(OPD_IPC_COMMANDS_FILE, "r");
+
+  if (!fp) {
+    printf("oprofiled: " OPD_IPC_COMMANDS_FILE " cannot be opened for reading\n");
+    return;
+  } else {
+    char *line;
+    
+    while(1) {
+      line = op_get_line(fp);
+
+      if(!line)
+	break;
+      printf("Read one mapping line\n");
+      opd_ipc_process_command(line);
+      free(line);
+    }
+
+    if(line)
+      free(line);
+    op_close_file(fp);
+  }
+  printf("opd_ipc_read_mapping_commands - out\n");
+}
diff -uarN oprofile.orig/daemon/opd_ipc_commands.h oprofile.mod/daemon/opd_ipc_commands.h
--- oprofile.orig/daemon/opd_ipc_commands.h	1969-12-31 17:00:00.000000000 -0700
+++ oprofile.mod/daemon/opd_ipc_commands.h	2004-11-11 16:16:35.000000000 -0700
@@ -0,0 +1,36 @@
+/**
+ * @file opd_ipc.h
+ *
+ * Process IPC control commands
+ *
+ * @remark Copyright 2002 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Kristis Makris
+ * @author John Levon
+ */
+
+
+#ifndef OPD_IPC_COMMANDS_H
+#define OPD_IPC_COMMANDS_H
+
+#include "op_types.h"
+
+/** Characters that may delimit daemon control commands when submitted
+    in text format */
+#define OPD_IPC_COMMANDS_DELIMITERS " \t\n\r"
+
+/** Command that indicates a module mapping should be added */
+#define OPD_IPC_COMMAND_ADD_MAPPING "add_mapping"
+
+/** Name of file in which control commands that must be reloaded are
+    saved */
+#define OPD_IPC_COMMANDS_FILE OP_BASE_DIR "oprofiled.commands"
+
+void opd_ipc_process_commands(char *commands);
+void opd_ipc_process_command(char *command);
+void opd_ipc_process_command_add_mapping(const char *original_command);
+void opd_ipc_save_mapping_command(const char *original_command);
+void opd_ipc_read_mapping_commands();
+
+#endif /* OPD_IPC_COMMANDS_H */
diff -uarN oprofile.orig/daemon/opd_kernel.c oprofile.mod/daemon/opd_kernel.c
--- oprofile.orig/daemon/opd_kernel.c	2004-01-29 13:00:26.000000000 -0700
+++ oprofile.mod/daemon/opd_kernel.c	2004-11-11 16:16:35.000000000 -0700
@@ -61,8 +61,8 @@
  * @param start start address
  * @param end end address
  */
-static struct kernel_image *
-opd_create_module(char const * name, vma_t start, vma_t end)
+struct kernel_image *
+opd_create_module_26(char const * name, vma_t start, vma_t end)
 {
 	struct kernel_image * image = xmalloc(sizeof(struct kernel_image));
 
@@ -71,6 +71,9 @@
 	image->end = end;
 	list_add(&image->list, &modules);
 
+	printf("Added a module for '%s', start=0x%lx, end=0x%lx\n",
+	       image->name, (unsigned long) image->start, (unsigned long) image->end);
+
 	return image;
 }
 
@@ -154,8 +157,8 @@
 			continue;
 		}
 
-		image = opd_create_module(module_name, start_address,
-		                          start_address + module_size);
+		image = opd_create_module_26(module_name, start_address,
+					     start_address + module_size);
 
 		verbprintf(vmodule, "module %s start %llx end %llx\n",
 			   image->name, image->start, image->end);
diff -uarN oprofile.orig/daemon/opd_kernel.h oprofile.mod/daemon/opd_kernel.h
--- oprofile.orig/daemon/opd_kernel.h	2003-09-24 14:21:14.000000000 -0700
+++ oprofile.mod/daemon/opd_kernel.h	2004-11-11 16:16:35.000000000 -0700
@@ -20,6 +20,9 @@
 /** create the kernel image */
 void opd_create_vmlinux(char const * name, char const * arg);
 
+/** create a module mapping */
+struct kernel_image *opd_create_module_26(char const * name, vma_t start, vma_t end);
+
 /** opd_reread_module_info - parse /proc/modules for kernel modules */
 void opd_reread_module_info(void);
 
diff -uarN oprofile.orig/daemon/opd_trans.c oprofile.mod/daemon/opd_trans.c
--- oprofile.orig/daemon/opd_trans.c	2004-01-29 13:00:26.000000000 -0700
+++ oprofile.mod/daemon/opd_trans.c	2004-11-11 16:16:35.000000000 -0700
@@ -15,6 +15,7 @@
 #include "opd_stats.h"
 #include "opd_printf.h"
 #include "opd_interface.h"
+#include "opd_ipc_commands.h"
  
 #include <limits.h>
 #include <string.h>
@@ -201,6 +202,7 @@
 {
 	verbprintf(vmodule, "MODULE_LOADED_CODE\n");
 	opd_reread_module_info();
+	opd_ipc_read_mapping_commands();
 	trans->current = NULL;
 }
 
diff -uarN oprofile.orig/daemon/oprofiled.c oprofile.mod/daemon/oprofiled.c
--- oprofile.orig/daemon/oprofiled.c	2004-05-28 10:21:39.000000000 -0700
+++ oprofile.mod/daemon/oprofiled.c	2004-11-11 16:16:35.000000000 -0700
@@ -14,6 +14,7 @@
 #include "oprofiled.h"
 #include "opd_printf.h"
 #include "opd_events.h"
+#include "opd_ipc.h"
 
 #include "op_config.h"
 #include "op_version.h"
@@ -247,6 +248,12 @@
 }
 
 
+static void opd_setup_ipc(void)
+{
+  opd_ipc_pipe_setup();
+}
+
+
 struct opd_hashed_name {
 	char * name;
 	struct list_head next;
@@ -463,6 +470,8 @@
 		exit(EXIT_FAILURE);
 	}
 
+	opd_setup_ipc();
+
 	opd_ops->start();
 
 	opd_ops->exit();
diff -uarN oprofile.orig/doc/internals.xml oprofile.mod/doc/internals.xml
--- oprofile.orig/doc/internals.xml	2004-11-07 10:21:44.000000000 -0700
+++ oprofile.mod/doc/internals.xml	2004-11-08 11:12:33.000000000 -0700
@@ -505,6 +505,27 @@
 </para>
 </sect1>
 
+
+<sect1 id="jit">
+<title>Just In Time generated code</title>
+
+<para>
+OProfile does not yet fully support reporting performance counters
+collected in regions of code produced by a Just In Time (JIT) tool,
+such as a Java or C# compiler.
+</para>
+
+<para>
+Reporting JIT code produced in userspace requires a great deal of
+coordination between the kernel driver and daemon. Plans for addition
+of this feature are in the works. However, performance counters on JIT
+code produced inside the kernel currently make it all the way to the
+daemon. While the daemon is running, it is possible to supply
+additional JIT module mappings using a named pipe. See
+daemon/opd_ipc.c for details.
+</para>
+</sect1>
+
 </chapter>
 
 <chapter id="sample-files">
