1 /* This test program is part of GDB, the GNU debugger.
3 Copyright 2011-2013 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. */
31 /* ElfW is coming from linux. On other platforms it does not exist.
32 Let us define it here. */
34 # if (defined (_LP64) || defined (__LP64__))
38 # endif /* _LP64 || __LP64__ */
39 #define ElfW(type) _ElfW (Elf, WORDSIZE, type)
40 #define _ElfW(e,w,t) _ElfW_1 (e, w, _##t)
41 #define _ElfW_1(e,w,t) e##w##t
53 struct jit_code_entry
*next_entry
;
54 struct jit_code_entry
*prev_entry
;
55 const char *symfile_addr
;
56 uint64_t symfile_size
;
62 /* This type should be jit_actions_t, but we use uint32_t
63 to be explicit about the bitwidth. */
65 struct jit_code_entry
*relevant_entry
;
66 struct jit_code_entry
*first_entry
;
69 /* GDB puts a breakpoint in this function. */
70 void __attribute__((noinline
)) __jit_debug_register_code () { }
72 /* Make sure to specify the version statically, because the
73 debugger may check the version before we can set it. */
74 struct jit_descriptor __jit_debug_descriptor
= { 1, 0, 0, 0 };
77 usage (const char *const argv0
)
79 fprintf (stderr
, "Usage: %s library [count]\n", argv0
);
83 /* Update .p_vaddr and .sh_addr as if the code was JITted to ADDR. */
86 update_locations (const void *const addr
, int idx
)
88 const ElfW (Ehdr
) *const ehdr
= (ElfW (Ehdr
) *)addr
;
89 ElfW (Shdr
) *const shdr
= (ElfW (Shdr
) *)((char *)addr
+ ehdr
->e_shoff
);
90 ElfW (Phdr
) *const phdr
= (ElfW (Phdr
) *)((char *)addr
+ ehdr
->e_phoff
);
93 for (i
= 0; i
< ehdr
->e_phnum
; ++i
)
94 if (phdr
[i
].p_type
== PT_LOAD
)
95 phdr
[i
].p_vaddr
+= (ElfW (Addr
))addr
;
97 for (i
= 0; i
< ehdr
->e_shnum
; ++i
)
99 if (shdr
[i
].sh_type
== SHT_STRTAB
)
101 /* Note: we update both .strtab and .dynstr. The latter would
102 not be correct if this were a regular shared library (.hash
103 would be wrong), but this is a simulation -- the library is
104 never exposed to the dynamic loader, so it all ends up ok. */
105 char *const strtab
= (char *)((ElfW (Addr
))addr
+ shdr
[i
].sh_offset
);
106 char *const strtab_end
= strtab
+ shdr
[i
].sh_size
;
109 for (p
= strtab
; p
< strtab_end
; p
+= strlen (p
) + 1)
110 if (strcmp (p
, "jit_function_XXXX") == 0)
111 sprintf (p
, "jit_function_%04d", idx
);
114 if (shdr
[i
].sh_flags
& SHF_ALLOC
)
115 shdr
[i
].sh_addr
+= (ElfW (Addr
))addr
;
124 MAIN (int argc
, char *argv
[])
126 /* These variables are here so they can easily be set from jit.exp. */
127 const char *libname
= NULL
;
130 count
= count
; /* gdb break here 0 */
140 /* Only set if not already set from GDB. */
143 if (argc
> 2 && count
== 0)
144 /* Only set if not already set from GDB. */
145 count
= atoi (argv
[2]);
147 printf ("%s:%d: libname = %s, count = %d\n", __FILE__
, __LINE__
,
150 if ((fd
= open (libname
, O_RDONLY
)) == -1)
152 fprintf (stderr
, "open (\"%s\", O_RDONLY): %s\n", libname
,
157 if (fstat (fd
, &st
) != 0)
159 fprintf (stderr
, "fstat (\"%d\"): %s\n", fd
, strerror (errno
));
163 for (i
= 0; i
< count
; ++i
)
165 const void *const addr
= mmap (0, st
.st_size
, PROT_READ
|PROT_WRITE
,
167 struct jit_code_entry
*const entry
= calloc (1, sizeof (*entry
));
169 if (addr
== MAP_FAILED
)
171 fprintf (stderr
, "mmap: %s\n", strerror (errno
));
175 update_locations (addr
, i
);
177 /* Link entry at the end of the list. */
178 entry
->symfile_addr
= (const char *)addr
;
179 entry
->symfile_size
= st
.st_size
;
180 entry
->prev_entry
= __jit_debug_descriptor
.relevant_entry
;
181 __jit_debug_descriptor
.relevant_entry
= entry
;
183 if (entry
->prev_entry
!= NULL
)
184 entry
->prev_entry
->next_entry
= entry
;
186 __jit_debug_descriptor
.first_entry
= entry
;
189 __jit_debug_descriptor
.action_flag
= JIT_REGISTER_FN
;
190 __jit_debug_register_code ();
193 i
= 0; /* gdb break here 1 */
195 /* Now unregister them all in reverse order. */
196 while (__jit_debug_descriptor
.relevant_entry
!= NULL
)
198 struct jit_code_entry
*const entry
=
199 __jit_debug_descriptor
.relevant_entry
;
200 struct jit_code_entry
*const prev_entry
= entry
->prev_entry
;
202 if (prev_entry
!= NULL
)
204 prev_entry
->next_entry
= NULL
;
205 entry
->prev_entry
= NULL
;
208 __jit_debug_descriptor
.first_entry
= NULL
;
211 __jit_debug_descriptor
.action_flag
= JIT_UNREGISTER_FN
;
212 __jit_debug_register_code ();
214 __jit_debug_descriptor
.relevant_entry
= prev_entry
;
218 return 0; /* gdb break here 2 */