1 /* This test program is part of GDB, the GNU debugger.
3 Copyright 2020-2023 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 /* Simulates loading of JIT code by memory mapping a compiled
19 shared library binary and doing minimal post-processing. */
33 /* ElfW is coming from linux. On other platforms it does not exist.
34 Let us define it here. */
36 #if (defined(_LP64) || defined(__LP64__))
40 #endif /* _LP64 || __LP64__ */
41 #define ElfW(type) _ElfW (Elf, WORDSIZE, type)
42 #define _ElfW(e, w, t) _ElfW_1 (e, w, _##t)
43 #define _ElfW_1(e, w, t) e##w##t
46 /* Find symbol with the name `sym_name`. */
48 load_symbol (void *addr
, const char *sym_name
)
50 const ElfW (Ehdr
) *const ehdr
= (ElfW (Ehdr
) *) addr
;
51 ElfW (Shdr
) *const shdr
= (ElfW (Shdr
) *) ((char *) addr
+ ehdr
->e_shoff
);
53 ElfW (Addr
) sym_old_addr
= 0;
54 ElfW (Addr
) sym_new_addr
= 0;
56 /* Find `func_name` in symbol_table and return its address. */
58 for (i
= 0; i
< ehdr
->e_shnum
; ++i
)
60 if (shdr
[i
].sh_type
== SHT_SYMTAB
)
62 ElfW (Sym
) *symtab
= (ElfW (Sym
) *) (addr
+ shdr
[i
].sh_offset
);
63 ElfW (Sym
) *symtab_end
64 = (ElfW (Sym
) *) (addr
+ shdr
[i
].sh_offset
+ shdr
[i
].sh_size
);
66 = (char *) (addr
+ shdr
[shdr
[i
].sh_link
].sh_offset
);
69 for (p
= symtab
; p
< symtab_end
; ++p
)
71 const char *s
= strtab
+ p
->st_name
;
72 if (strcmp (s
, sym_name
) == 0)
73 return (void *) p
->st_value
;
78 fprintf (stderr
, "symbol '%s' not found\n", sym_name
);
83 /* Open an elf binary file and memory map it with execution flag enabled. */
85 load_elf (const char *libname
, size_t *size
, void *load_addr
)
90 if ((fd
= open (libname
, O_RDONLY
)) == -1)
92 fprintf (stderr
, "open (\"%s\", O_RDONLY): %s\n", libname
,
97 if (fstat (fd
, &st
) != 0)
99 fprintf (stderr
, "fstat (\"%d\"): %s\n", fd
, strerror (errno
));
103 void *addr
= mmap (load_addr
, st
.st_size
,
104 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
105 load_addr
!= NULL
? MAP_PRIVATE
| MAP_FIXED
: MAP_PRIVATE
,
109 if (addr
== MAP_FAILED
)
111 fprintf (stderr
, "mmap: %s\n", strerror (errno
));