aboutsummaryrefslogtreecommitdiffstats
path: root/arch/tile
diff options
context:
space:
mode:
authorChris Metcalf <cmetcalf@tilera.com>2013-08-07 14:07:03 -0400
committerChris Metcalf <cmetcalf@tilera.com>2013-08-13 16:26:17 -0400
commit0c1d1917c547c8e787fb58e20e2de577453c980c (patch)
tree35673bc9af034c859132f7f6c90edb1937997e7e /arch/tile
parent70d2b5958a04139fbffecf27791cf913dce8038e (diff)
tile: support simulator notification for ET_DYN objects
The tile code notifies the simulator of new ET_EXEC objects starting to execute so that tracing code can properly annotate the objects. However, we didn't support ET_DYN executables like ld.so, so we didn't properly load symbols, etc. This change enables that support; we use a variant of the SIM_CONTROL_DLOPEN simulator notification that newer simulators will recognize and use to set the base address for the next SIM_CONTROL_OS_EXEC notification. Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r--arch/tile/mm/elf.c62
1 files changed, 48 insertions, 14 deletions
diff --git a/arch/tile/mm/elf.c b/arch/tile/mm/elf.c
index 743c951c61b0..1691b81b2b0c 100644
--- a/arch/tile/mm/elf.c
+++ b/arch/tile/mm/elf.c
@@ -21,7 +21,7 @@
21#include <asm/pgtable.h> 21#include <asm/pgtable.h>
22#include <asm/pgalloc.h> 22#include <asm/pgalloc.h>
23#include <asm/sections.h> 23#include <asm/sections.h>
24#include <arch/sim_def.h> 24#include <arch/sim.h>
25 25
26/* Notify a running simulator, if any, that an exec just occurred. */ 26/* Notify a running simulator, if any, that an exec just occurred. */
27static void sim_notify_exec(const char *binary_name) 27static void sim_notify_exec(const char *binary_name)
@@ -38,21 +38,55 @@ static void sim_notify_exec(const char *binary_name)
38 38
39static int notify_exec(struct mm_struct *mm) 39static int notify_exec(struct mm_struct *mm)
40{ 40{
41 int retval = 0; /* failure */ 41 char *buf, *path;
42 42 struct vm_area_struct *vma;
43 if (mm->exe_file) { 43
44 char *buf = (char *) __get_free_page(GFP_KERNEL); 44 if (!sim_is_simulator())
45 if (buf) { 45 return 1;
46 char *path = d_path(&mm->exe_file->f_path, 46
47 buf, PAGE_SIZE); 47 if (mm->exe_file == NULL)
48 if (!IS_ERR(path)) { 48 return 0;
49 sim_notify_exec(path); 49
50 retval = 1; 50 for (vma = current->mm->mmap; ; vma = vma->vm_next) {
51 } 51 if (vma == NULL)
52 free_page((unsigned long)buf); 52 return 0;
53 if (vma->vm_file == mm->exe_file)
54 break;
55 }
56
57 buf = (char *) __get_free_page(GFP_KERNEL);
58 if (buf == NULL)
59 return 0;
60
61 path = d_path(&mm->exe_file->f_path, buf, PAGE_SIZE);
62 if (IS_ERR(path)) {
63 free_page((unsigned long)buf);
64 return 0;
65 }
66
67 /*
68 * Notify simulator of an ET_DYN object so we know the load address.
69 * The somewhat cryptic overuse of SIM_CONTROL_DLOPEN allows us
70 * to be backward-compatible with older simulator releases.
71 */
72 if (vma->vm_start == (ELF_ET_DYN_BASE & PAGE_MASK)) {
73 char buf[64];
74 int i;
75
76 snprintf(buf, sizeof(buf), "0x%lx:@", vma->vm_start);
77 for (i = 0; ; ++i) {
78 char c = buf[i];
79 __insn_mtspr(SPR_SIM_CONTROL,
80 (SIM_CONTROL_DLOPEN
81 | (c << _SIM_CONTROL_OPERATOR_BITS)));
82 if (c == '\0')
83 break;
53 } 84 }
54 } 85 }
55 return retval; 86
87 sim_notify_exec(path);
88 free_page((unsigned long)buf);
89 return 1;
56} 90}
57 91
58/* Notify a running simulator, if any, that we loaded an interpreter. */ 92/* Notify a running simulator, if any, that we loaded an interpreter. */