diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-07 14:07:03 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2013-08-13 16:26:17 -0400 |
commit | 0c1d1917c547c8e787fb58e20e2de577453c980c (patch) | |
tree | 35673bc9af034c859132f7f6c90edb1937997e7e /arch/tile | |
parent | 70d2b5958a04139fbffecf27791cf913dce8038e (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.c | 62 |
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. */ |
27 | static void sim_notify_exec(const char *binary_name) | 27 | static void sim_notify_exec(const char *binary_name) |
@@ -38,21 +38,55 @@ static void sim_notify_exec(const char *binary_name) | |||
38 | 38 | ||
39 | static int notify_exec(struct mm_struct *mm) | 39 | static 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. */ |