1 /* interp.c -- AArch64 sim interface to GDB. 2 3 Copyright (C) 2015-2024 Free Software Foundation, Inc. 4 5 Contributed by Red Hat. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 /* This must come before any other includes. */ 23 #include "defs.h" 24 25 #include <stdio.h> 26 #include <assert.h> 27 #include <signal.h> 28 #include <string.h> 29 #include <ctype.h> 30 #include <stdlib.h> 31 32 #include "ansidecl.h" 33 #include "bfd.h" 34 #include "sim/callback.h" 35 #include "sim/sim.h" 36 #include "gdb/signals.h" 37 #include "sim/sim-aarch64.h" 38 39 #include "sim-main.h" 40 #include "sim-options.h" 41 #include "memory.h" 42 #include "simulator.h" 43 #include "sim-assert.h" 44 45 #include "aarch64-sim.h" 46 47 /* Filter out (in place) symbols that are useless for disassembly. 48 COUNT is the number of elements in SYMBOLS. 49 Return the number of useful symbols. */ 50 51 static long 52 remove_useless_symbols (asymbol **symbols, long count) 53 { 54 asymbol **in_ptr = symbols; 55 asymbol **out_ptr = symbols; 56 57 while (count-- > 0) 58 { 59 asymbol *sym = *in_ptr++; 60 61 if (strstr (sym->name, "gcc2_compiled")) 62 continue; 63 if (sym->name == NULL || sym->name[0] == '\0') 64 continue; 65 if (sym->flags & (BSF_DEBUGGING)) 66 continue; 67 if ( bfd_is_und_section (sym->section) 68 || bfd_is_com_section (sym->section)) 69 continue; 70 if (sym->name[0] == '$') 71 continue; 72 73 *out_ptr++ = sym; 74 } 75 return out_ptr - symbols; 76 } 77 78 static signed int 79 compare_symbols (const void *ap, const void *bp) 80 { 81 const asymbol *a = * (const asymbol **) ap; 82 const asymbol *b = * (const asymbol **) bp; 83 84 if (bfd_asymbol_value (a) > bfd_asymbol_value (b)) 85 return 1; 86 if (bfd_asymbol_value (a) < bfd_asymbol_value (b)) 87 return -1; 88 return 0; 89 } 90 91 /* Find the name of the function at ADDR. */ 92 const char * 93 aarch64_get_func (SIM_DESC sd, uint64_t addr) 94 { 95 long symcount = STATE_PROG_SYMS_COUNT (sd); 96 asymbol **symtab = STATE_PROG_SYMS (sd); 97 int min, max; 98 99 min = -1; 100 max = symcount; 101 while (min < max - 1) 102 { 103 int sym; 104 bfd_vma sa; 105 106 sym = (min + max) / 2; 107 sa = bfd_asymbol_value (symtab[sym]); 108 109 if (sa > addr) 110 max = sym; 111 else if (sa < addr) 112 min = sym; 113 else 114 { 115 min = sym; 116 break; 117 } 118 } 119 120 if (min != -1) 121 return bfd_asymbol_name (symtab [min]); 122 123 return ""; 124 } 125 126 SIM_RC 127 sim_create_inferior (SIM_DESC sd, struct bfd *abfd, 128 char * const *argv, char * const *env) 129 { 130 sim_cpu *cpu = STATE_CPU (sd, 0); 131 host_callback *cb = STATE_CALLBACK (sd); 132 bfd_vma addr = 0; 133 134 if (abfd != NULL) 135 addr = bfd_get_start_address (abfd); 136 137 aarch64_set_next_PC (cpu, addr); 138 aarch64_update_PC (cpu); 139 140 /* Standalone mode (i.e. `run`) will take care of the argv for us in 141 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim' 142 with `gdb`), we need to handle it because the user can change the 143 argv on the fly via gdb's 'run'. */ 144 if (STATE_PROG_ARGV (sd) != argv) 145 { 146 freeargv (STATE_PROG_ARGV (sd)); 147 STATE_PROG_ARGV (sd) = dupargv (argv); 148 } 149 150 if (STATE_PROG_ENVP (sd) != env) 151 { 152 freeargv (STATE_PROG_ENVP (sd)); 153 STATE_PROG_ENVP (sd) = dupargv (env); 154 } 155 156 cb->argv = STATE_PROG_ARGV (sd); 157 cb->envp = STATE_PROG_ENVP (sd); 158 159 if (trace_load_symbols (sd)) 160 { 161 STATE_PROG_SYMS_COUNT (sd) = 162 remove_useless_symbols (STATE_PROG_SYMS (sd), 163 STATE_PROG_SYMS_COUNT (sd)); 164 qsort (STATE_PROG_SYMS (sd), STATE_PROG_SYMS_COUNT (sd), 165 sizeof (asymbol *), compare_symbols); 166 } 167 168 aarch64_init (cpu, addr); 169 170 return SIM_RC_OK; 171 } 172 173 /* Read the LENGTH bytes at BUF as a little-endian value. */ 174 175 static bfd_vma 176 get_le (const unsigned char *buf, unsigned int length) 177 { 178 bfd_vma acc = 0; 179 180 while (length -- > 0) 181 acc = (acc << 8) + buf[length]; 182 183 return acc; 184 } 185 186 /* Store VAL as a little-endian value in the LENGTH bytes at BUF. */ 187 188 static void 189 put_le (unsigned char *buf, unsigned int length, bfd_vma val) 190 { 191 int i; 192 193 for (i = 0; i < length; i++) 194 { 195 buf[i] = val & 0xff; 196 val >>= 8; 197 } 198 } 199 200 static int 201 check_regno (int regno) 202 { 203 return 0 <= regno && regno < AARCH64_MAX_REGNO; 204 } 205 206 static size_t 207 reg_size (int regno) 208 { 209 if (regno == AARCH64_CPSR_REGNO || regno == AARCH64_FPSR_REGNO) 210 return 32; 211 return 64; 212 } 213 214 static int 215 aarch64_reg_get (SIM_CPU *cpu, int regno, void *buf, int length) 216 { 217 size_t size; 218 bfd_vma val; 219 220 if (!check_regno (regno)) 221 return 0; 222 223 size = reg_size (regno); 224 225 if (length != size) 226 return 0; 227 228 switch (regno) 229 { 230 case AARCH64_MIN_GR ... AARCH64_MAX_GR: 231 val = aarch64_get_reg_u64 (cpu, regno, 0); 232 break; 233 234 case AARCH64_MIN_FR ... AARCH64_MAX_FR: 235 val = aarch64_get_FP_double (cpu, regno - 32); 236 break; 237 238 case AARCH64_PC_REGNO: 239 val = aarch64_get_PC (cpu); 240 break; 241 242 case AARCH64_CPSR_REGNO: 243 val = aarch64_get_CPSR (cpu); 244 break; 245 246 case AARCH64_FPSR_REGNO: 247 val = aarch64_get_FPSR (cpu); 248 break; 249 250 default: 251 sim_io_eprintf (CPU_STATE (cpu), 252 "sim: unrecognized register number: %d\n", regno); 253 return -1; 254 } 255 256 put_le (buf, length, val); 257 258 return size; 259 } 260 261 static int 262 aarch64_reg_set (SIM_CPU *cpu, int regno, const void *buf, int length) 263 { 264 size_t size; 265 bfd_vma val; 266 267 if (!check_regno (regno)) 268 return -1; 269 270 size = reg_size (regno); 271 272 if (length != size) 273 return -1; 274 275 val = get_le (buf, length); 276 277 switch (regno) 278 { 279 case AARCH64_MIN_GR ... AARCH64_MAX_GR: 280 aarch64_set_reg_u64 (cpu, regno, 1, val); 281 break; 282 283 case AARCH64_MIN_FR ... AARCH64_MAX_FR: 284 aarch64_set_FP_double (cpu, regno - 32, (double) val); 285 break; 286 287 case AARCH64_PC_REGNO: 288 aarch64_set_next_PC (cpu, val); 289 aarch64_update_PC (cpu); 290 break; 291 292 case AARCH64_CPSR_REGNO: 293 aarch64_set_CPSR (cpu, val); 294 break; 295 296 case AARCH64_FPSR_REGNO: 297 aarch64_set_FPSR (cpu, val); 298 break; 299 300 default: 301 sim_io_eprintf (CPU_STATE (cpu), 302 "sim: unrecognized register number: %d\n", regno); 303 return 0; 304 } 305 306 return size; 307 } 308 309 static sim_cia 310 aarch64_pc_get (sim_cpu *cpu) 311 { 312 return aarch64_get_PC (cpu); 313 } 314 315 static void 316 aarch64_pc_set (sim_cpu *cpu, sim_cia pc) 317 { 318 aarch64_set_next_PC (cpu, pc); 319 aarch64_update_PC (cpu); 320 } 321 322 static void 323 free_state (SIM_DESC sd) 324 { 325 if (STATE_MODULES (sd) != NULL) 326 sim_module_uninstall (sd); 327 sim_cpu_free_all (sd); 328 sim_state_free (sd); 329 } 330 331 SIM_DESC 332 sim_open (SIM_OPEN_KIND kind, 333 struct host_callback_struct * callback, 334 struct bfd * abfd, 335 char * const * argv) 336 { 337 sim_cpu *cpu; 338 SIM_DESC sd = sim_state_alloc (kind, callback); 339 340 if (sd == NULL) 341 return sd; 342 343 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 344 345 /* We use NONSTRICT_ALIGNMENT as the default because AArch64 only enforces 346 4-byte alignment, even for 8-byte reads/writes. The common core does not 347 support this, so we opt for non-strict alignment instead. */ 348 current_alignment = NONSTRICT_ALIGNMENT; 349 350 /* Perform the initialization steps one by one. */ 351 if (sim_cpu_alloc_all_extra (sd, 0, sizeof (struct aarch64_sim_cpu)) 352 != SIM_RC_OK 353 || sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK 354 || sim_parse_args (sd, argv) != SIM_RC_OK 355 || sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK 356 || sim_config (sd) != SIM_RC_OK 357 || sim_post_argv_init (sd) != SIM_RC_OK) 358 { 359 free_state (sd); 360 return NULL; 361 } 362 363 aarch64_init_LIT_table (); 364 365 assert (MAX_NR_PROCESSORS == 1); 366 cpu = STATE_CPU (sd, 0); 367 CPU_PC_FETCH (cpu) = aarch64_pc_get; 368 CPU_PC_STORE (cpu) = aarch64_pc_set; 369 CPU_REG_FETCH (cpu) = aarch64_reg_get; 370 CPU_REG_STORE (cpu) = aarch64_reg_set; 371 372 /* Set SP, FP and PC to 0 and set LR to -1 373 so we can detect a top-level return. */ 374 aarch64_set_reg_u64 (cpu, SP, 1, 0); 375 aarch64_set_reg_u64 (cpu, FP, 1, 0); 376 aarch64_set_reg_u64 (cpu, LR, 1, TOP_LEVEL_RETURN_PC); 377 aarch64_set_next_PC (cpu, 0); 378 aarch64_update_PC (cpu); 379 380 /* Default to a 128 Mbyte (== 2^27) memory space. */ 381 sim_do_commandf (sd, "memory-size 0x8000000"); 382 383 return sd; 384 } 385 386 void 387 sim_engine_run (SIM_DESC sd, 388 int next_cpu_nr ATTRIBUTE_UNUSED, 389 int nr_cpus ATTRIBUTE_UNUSED, 390 int siggnal ATTRIBUTE_UNUSED) 391 { 392 aarch64_run (sd); 393 } 394