1/* This test program is part of GDB, the GNU debugger.
2
3   Copyright 2011-2020 Free Software Foundation, Inc.
4
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.
9
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.
14
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/>.  */
17
18/* Simulate loading of JIT code.  */
19
20#include <elf.h>
21#include <link.h>
22#include <errno.h>
23#include <fcntl.h>
24#include <stdint.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <sys/mman.h>
29#include <sys/stat.h>
30#include <unistd.h>
31
32#include "jit-protocol.h"
33#include "jit-elf-util.h"
34
35static void
36usage (void)
37{
38  fprintf (stderr, "Usage: jit-elf-main libraries...\n");
39  exit (1);
40}
41
42/* Defined by the .exp file if testing attach.  */
43#ifndef ATTACH
44#define ATTACH 0
45#endif
46
47#ifndef MAIN
48#define MAIN main
49#endif
50
51/* Must be defined by .exp file when compiling to know
52   what address to map the ELF binary to.  */
53#ifndef LOAD_ADDRESS
54#error "Must define LOAD_ADDRESS"
55#endif
56#ifndef LOAD_INCREMENT
57#error "Must define LOAD_INCREMENT"
58#endif
59
60/* Used to spin waiting for GDB.  */
61volatile int wait_for_gdb = ATTACH;
62#define WAIT_FOR_GDB do {} while (wait_for_gdb)
63
64/* The current process's PID.  GDB retrieves this.  */
65int mypid;
66
67int
68MAIN (int argc, char *argv[])
69{
70  int i;
71  alarm (300);
72  /* Used as backing storage for GDB to populate argv.  */
73  char *fake_argv[10];
74
75  mypid = getpid ();
76  /* gdb break here 0  */
77
78  if (argc < 2)
79    {
80      usage ();
81      exit (1);
82    }
83
84  for (i = 1; i < argc; ++i)
85    {
86      size_t obj_size;
87      void *load_addr = (void *) (size_t) (LOAD_ADDRESS + (i - 1) * LOAD_INCREMENT);
88      printf ("Loading %s as JIT at %p\n", argv[i], load_addr);
89      void *addr = load_elf (argv[i], &obj_size, load_addr);
90
91      char name[32];
92      sprintf (name, "jit_function_%04d", i);
93      int (*jit_function) (void) = (int (*) (void)) load_symbol (addr, name);
94
95      /* Link entry at the end of the list.  */
96      struct jit_code_entry *const entry = calloc (1, sizeof (*entry));
97      entry->symfile_addr = (const char *)addr;
98      entry->symfile_size = obj_size;
99      entry->prev_entry = __jit_debug_descriptor.relevant_entry;
100      __jit_debug_descriptor.relevant_entry = entry;
101
102      if (entry->prev_entry != NULL)
103	entry->prev_entry->next_entry = entry;
104      else
105	__jit_debug_descriptor.first_entry = entry;
106
107      /* Notify GDB.  */
108      __jit_debug_descriptor.action_flag = JIT_REGISTER;
109      __jit_debug_register_code ();
110
111      if (jit_function () != 42)
112	{
113	  fprintf (stderr, "unexpected return value\n");
114	  exit (1);
115	}
116    }
117
118  WAIT_FOR_GDB; i = 0;  /* gdb break here 1 */
119
120  /* Now unregister them all in reverse order.  */
121  while (__jit_debug_descriptor.relevant_entry != NULL)
122    {
123      struct jit_code_entry *const entry =
124	__jit_debug_descriptor.relevant_entry;
125      struct jit_code_entry *const prev_entry = entry->prev_entry;
126
127      if (prev_entry != NULL)
128	{
129	  prev_entry->next_entry = NULL;
130	  entry->prev_entry = NULL;
131	}
132      else
133	__jit_debug_descriptor.first_entry = NULL;
134
135      /* Notify GDB.  */
136      __jit_debug_descriptor.action_flag = JIT_UNREGISTER;
137      __jit_debug_register_code ();
138
139      __jit_debug_descriptor.relevant_entry = prev_entry;
140      free (entry);
141    }
142
143  WAIT_FOR_GDB; return 0;  /* gdb break here 2  */
144}
145