1 /* This test program is part of GDB, the GNU debugger.
3 Copyright 2011-2016 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 /* Simulate loading of JIT code. */
32 /* ElfW is coming from linux. On other platforms it does not exist.
33 Let us define it here. */
35 # if (defined (_LP64) || defined (__LP64__))
39 # endif /* _LP64 || __LP64__ */
40 #define ElfW(type) _ElfW (Elf, WORDSIZE, type)
41 #define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
42 #define _ElfW_1(e,w,t) e##w##t
54 struct jit_code_entry
*next_entry
;
55 struct jit_code_entry
*prev_entry
;
56 const char *symfile_addr
;
57 uint64_t symfile_size
;
63 /* This type should be jit_actions_t, but we use uint32_t
64 to be explicit about the bitwidth. */
66 struct jit_code_entry
*relevant_entry
;
67 struct jit_code_entry
*first_entry
;
70 /* GDB puts a breakpoint in this function. */
71 void __attribute__((noinline
)) __jit_debug_register_code () { }
73 /* Make sure to specify the version statically, because the
74 debugger may check the version before we can set it. */
75 struct jit_descriptor __jit_debug_descriptor
= { 1, 0, 0, 0 };
78 usage (const char *const argv0
)
80 fprintf (stderr
, "Usage: %s library [count]\n", argv0
);
84 /* Update .p_vaddr and .sh_addr as if the code was JITted to ADDR. */
87 update_locations (const void *const addr
, int idx
)
89 const ElfW (Ehdr
) *const ehdr
= (ElfW (Ehdr
) *)addr
;
90 ElfW (Shdr
) *const shdr
= (ElfW (Shdr
) *)((char *)addr
+ ehdr
->e_shoff
);
91 ElfW (Phdr
) *const phdr
= (ElfW (Phdr
) *)((char *)addr
+ ehdr
->e_phoff
);
94 for (i
= 0; i
< ehdr
->e_phnum
; ++i
)
95 if (phdr
[i
].p_type
== PT_LOAD
)
96 phdr
[i
].p_vaddr
+= (ElfW (Addr
))addr
;
98 for (i
= 0; i
< ehdr
->e_shnum
; ++i
)
100 if (shdr
[i
].sh_type
== SHT_STRTAB
)
102 /* Note: we update both .strtab and .dynstr. The latter would
103 not be correct if this were a regular shared library (.hash
104 would be wrong), but this is a simulation -- the library is
105 never exposed to the dynamic loader, so it all ends up ok. */
106 char *const strtab
= (char *)((ElfW (Addr
))addr
+ shdr
[i
].sh_offset
);
107 char *const strtab_end
= strtab
+ shdr
[i
].sh_size
;
110 for (p
= strtab
; p
< strtab_end
; p
+= strlen (p
) + 1)
111 if (strcmp (p
, "jit_function_XXXX") == 0)
112 sprintf (p
, "jit_function_%04d", idx
);
115 if (shdr
[i
].sh_flags
& SHF_ALLOC
)
116 shdr
[i
].sh_addr
+= (ElfW (Addr
))addr
;
120 /* Defined by the .exp file if testing attach. */
129 /* Used to spin waiting for GDB. */
130 volatile int wait_for_gdb
= ATTACH
;
131 #define WAIT_FOR_GDB while (wait_for_gdb)
133 /* The current process's PID. GDB retrieves this. */
137 MAIN (int argc
, char *argv
[])
139 /* These variables are here so they can easily be set from jit.exp. */
140 const char *libname
= NULL
;
147 count
= count
; /* gdb break here 0 */
157 /* Only set if not already set from GDB. */
160 if (argc
> 2 && count
== 0)
161 /* Only set if not already set from GDB. */
162 count
= atoi (argv
[2]);
164 printf ("%s:%d: libname = %s, count = %d\n", __FILE__
, __LINE__
,
167 if ((fd
= open (libname
, O_RDONLY
)) == -1)
169 fprintf (stderr
, "open (\"%s\", O_RDONLY): %s\n", libname
,
174 if (fstat (fd
, &st
) != 0)
176 fprintf (stderr
, "fstat (\"%d\"): %s\n", fd
, strerror (errno
));
180 for (i
= 0; i
< count
; ++i
)
182 const void *const addr
= mmap (0, st
.st_size
, PROT_READ
|PROT_WRITE
,
184 struct jit_code_entry
*const entry
= calloc (1, sizeof (*entry
));
186 if (addr
== MAP_FAILED
)
188 fprintf (stderr
, "mmap: %s\n", strerror (errno
));
192 update_locations (addr
, i
);
194 /* Link entry at the end of the list. */
195 entry
->symfile_addr
= (const char *)addr
;
196 entry
->symfile_size
= st
.st_size
;
197 entry
->prev_entry
= __jit_debug_descriptor
.relevant_entry
;
198 __jit_debug_descriptor
.relevant_entry
= entry
;
200 if (entry
->prev_entry
!= NULL
)
201 entry
->prev_entry
->next_entry
= entry
;
203 __jit_debug_descriptor
.first_entry
= entry
;
206 __jit_debug_descriptor
.action_flag
= JIT_REGISTER_FN
;
207 __jit_debug_register_code ();
210 WAIT_FOR_GDB
; i
= 0; /* gdb break here 1 */
212 /* Now unregister them all in reverse order. */
213 while (__jit_debug_descriptor
.relevant_entry
!= NULL
)
215 struct jit_code_entry
*const entry
=
216 __jit_debug_descriptor
.relevant_entry
;
217 struct jit_code_entry
*const prev_entry
= entry
->prev_entry
;
219 if (prev_entry
!= NULL
)
221 prev_entry
->next_entry
= NULL
;
222 entry
->prev_entry
= NULL
;
225 __jit_debug_descriptor
.first_entry
= NULL
;
228 __jit_debug_descriptor
.action_flag
= JIT_UNREGISTER_FN
;
229 __jit_debug_register_code ();
231 __jit_debug_descriptor
.relevant_entry
= prev_entry
;
235 WAIT_FOR_GDB
; return 0; /* gdb break here 2 */