| OLD | NEW |
| 1 /* Tracepoint code for remote server for GDB. | 1 /* Tracepoint code for remote server for GDB. |
| 2 Copyright (C) 2009-2012 Free Software Foundation, Inc. | 2 Copyright (C) 2009-2012 Free Software Foundation, Inc. |
| 3 | 3 |
| 4 This file is part of GDB. | 4 This file is part of GDB. |
| 5 | 5 |
| 6 This program is free software; you can redistribute it and/or modify | 6 This program is free software; you can redistribute it and/or modify |
| 7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
| 8 the Free Software Foundation; either version 3 of the License, or | 8 the Free Software Foundation; either version 3 of the License, or |
| 9 (at your option) any later version. | 9 (at your option) any later version. |
| 10 | 10 |
| 11 This program is distributed in the hope that it will be useful, | 11 This program is distributed in the hope that it will be useful, |
| 12 but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 GNU General Public License for more details. | 14 GNU General Public License for more details. |
| 15 | 15 |
| 16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
| 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
| 18 | 18 |
| 19 #include "server.h" | 19 #include "server.h" |
| 20 #include "gdbthread.h" |
| 21 #include "agent.h" |
| 22 |
| 20 #include <ctype.h> | 23 #include <ctype.h> |
| 21 #include <fcntl.h> | 24 #include <fcntl.h> |
| 22 #include <unistd.h> | 25 #include <unistd.h> |
| 23 #include <sys/time.h> | 26 #include <sys/time.h> |
| 24 #include <stddef.h> | 27 #include <stddef.h> |
| 25 #if HAVE_STDINT_H | 28 #include <inttypes.h> |
| 26 #include <stdint.h> | 29 #include <stdint.h> |
| 27 #endif | 30 |
| 31 #include "ax.h" |
| 28 | 32 |
| 29 /* This file is built for both GDBserver, and the in-process | 33 /* This file is built for both GDBserver, and the in-process |
| 30 agent (IPA), a shared library that includes a tracing agent that is | 34 agent (IPA), a shared library that includes a tracing agent that is |
| 31 loaded by the inferior to support fast tracepoints. Fast | 35 loaded by the inferior to support fast tracepoints. Fast |
| 32 tracepoints (or more accurately, jump based tracepoints) are | 36 tracepoints (or more accurately, jump based tracepoints) are |
| 33 implemented by patching the tracepoint location with a jump into a | 37 implemented by patching the tracepoint location with a jump into a |
| 34 small trampoline function whose job is to save the register state, | 38 small trampoline function whose job is to save the register state, |
| 35 call the in-process tracing agent, and then execute the original | 39 call the in-process tracing agent, and then execute the original |
| 36 instruction that was under the tracepoint jump (possibly adjusted, | 40 instruction that was under the tracepoint jump (possibly adjusted, |
| 37 if PC-relative, or some such). | 41 if PC-relative, or some such). |
| (...skipping 18 matching lines...) Expand all Loading... |
| 56 static void trace_vdebug (const char *, ...) ATTR_FORMAT (printf, 1, 2); | 60 static void trace_vdebug (const char *, ...) ATTR_FORMAT (printf, 1, 2); |
| 57 | 61 |
| 58 static void | 62 static void |
| 59 trace_vdebug (const char *fmt, ...) | 63 trace_vdebug (const char *fmt, ...) |
| 60 { | 64 { |
| 61 char buf[1024]; | 65 char buf[1024]; |
| 62 va_list ap; | 66 va_list ap; |
| 63 | 67 |
| 64 va_start (ap, fmt); | 68 va_start (ap, fmt); |
| 65 vsprintf (buf, fmt, ap); | 69 vsprintf (buf, fmt, ap); |
| 66 fprintf (stderr, "gdbserver/tracepoint: %s\n", buf); | 70 fprintf (stderr, PROG "/tracepoint: %s\n", buf); |
| 67 va_end (ap); | 71 va_end (ap); |
| 68 } | 72 } |
| 69 | 73 |
| 70 #define trace_debug_1(level, fmt, args...) \ | 74 #define trace_debug_1(level, fmt, args...) \ |
| 71 do { \ | 75 do { \ |
| 72 if (level <= debug_threads)»» » \ | 76 if (level <= debug_threads)»» \ |
| 73 trace_vdebug ((fmt), ##args); \ | 77 trace_vdebug ((fmt), ##args); \ |
| 74 } while (0) | 78 } while (0) |
| 75 | 79 |
| 76 #define trace_debug(FMT, args...) \ | 80 #define trace_debug(FMT, args...) \ |
| 77 trace_debug_1 (1, FMT, ##args) | 81 trace_debug_1 (1, FMT, ##args) |
| 78 | 82 |
| 79 #if defined(__GNUC__) | 83 #if defined(__GNUC__) |
| 80 # define ATTR_USED __attribute__((used)) | 84 # define ATTR_USED __attribute__((used)) |
| 81 # define ATTR_NOINLINE __attribute__((noinline)) | 85 # define ATTR_NOINLINE __attribute__((noinline)) |
| 82 # define ATTR_CONSTRUCTOR __attribute__ ((constructor)) | 86 # define ATTR_CONSTRUCTOR __attribute__ ((constructor)) |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 CORE_ADDR addr_trace_buffer_lo; | 174 CORE_ADDR addr_trace_buffer_lo; |
| 171 CORE_ADDR addr_trace_buffer_hi; | 175 CORE_ADDR addr_trace_buffer_hi; |
| 172 CORE_ADDR addr_traceframe_read_count; | 176 CORE_ADDR addr_traceframe_read_count; |
| 173 CORE_ADDR addr_traceframe_write_count; | 177 CORE_ADDR addr_traceframe_write_count; |
| 174 CORE_ADDR addr_traceframes_created; | 178 CORE_ADDR addr_traceframes_created; |
| 175 CORE_ADDR addr_trace_state_variables; | 179 CORE_ADDR addr_trace_state_variables; |
| 176 CORE_ADDR addr_get_raw_reg; | 180 CORE_ADDR addr_get_raw_reg; |
| 177 CORE_ADDR addr_get_trace_state_variable_value; | 181 CORE_ADDR addr_get_trace_state_variable_value; |
| 178 CORE_ADDR addr_set_trace_state_variable_value; | 182 CORE_ADDR addr_set_trace_state_variable_value; |
| 179 CORE_ADDR addr_ust_loaded; | 183 CORE_ADDR addr_ust_loaded; |
| 180 CORE_ADDR addr_helper_thread_id; | |
| 181 CORE_ADDR addr_cmd_buf; | |
| 182 }; | 184 }; |
| 183 | 185 |
| 184 #define STRINGIZE_1(STR) #STR | |
| 185 #define STRINGIZE(STR) STRINGIZE_1(STR) | |
| 186 #define IPA_SYM(SYM) \ | |
| 187 { \ | |
| 188 STRINGIZE (gdb_agent_ ## SYM), \ | |
| 189 offsetof (struct ipa_sym_addresses, addr_ ## SYM) \ | |
| 190 } | |
| 191 | |
| 192 static struct | 186 static struct |
| 193 { | 187 { |
| 194 const char *name; | 188 const char *name; |
| 195 int offset; | 189 int offset; |
| 196 int required; | 190 int required; |
| 197 } symbol_list[] = { | 191 } symbol_list[] = { |
| 198 IPA_SYM(gdb_tp_heap_buffer), | 192 IPA_SYM(gdb_tp_heap_buffer), |
| 199 IPA_SYM(gdb_jump_pad_buffer), | 193 IPA_SYM(gdb_jump_pad_buffer), |
| 200 IPA_SYM(gdb_jump_pad_buffer_end), | 194 IPA_SYM(gdb_jump_pad_buffer_end), |
| 201 IPA_SYM(gdb_trampoline_buffer), | 195 IPA_SYM(gdb_trampoline_buffer), |
| (...skipping 15 matching lines...) Expand all Loading... |
| 217 IPA_SYM(trace_buffer_lo), | 211 IPA_SYM(trace_buffer_lo), |
| 218 IPA_SYM(trace_buffer_hi), | 212 IPA_SYM(trace_buffer_hi), |
| 219 IPA_SYM(traceframe_read_count), | 213 IPA_SYM(traceframe_read_count), |
| 220 IPA_SYM(traceframe_write_count), | 214 IPA_SYM(traceframe_write_count), |
| 221 IPA_SYM(traceframes_created), | 215 IPA_SYM(traceframes_created), |
| 222 IPA_SYM(trace_state_variables), | 216 IPA_SYM(trace_state_variables), |
| 223 IPA_SYM(get_raw_reg), | 217 IPA_SYM(get_raw_reg), |
| 224 IPA_SYM(get_trace_state_variable_value), | 218 IPA_SYM(get_trace_state_variable_value), |
| 225 IPA_SYM(set_trace_state_variable_value), | 219 IPA_SYM(set_trace_state_variable_value), |
| 226 IPA_SYM(ust_loaded), | 220 IPA_SYM(ust_loaded), |
| 227 IPA_SYM(helper_thread_id), | |
| 228 IPA_SYM(cmd_buf), | |
| 229 }; | 221 }; |
| 230 | 222 |
| 231 struct ipa_sym_addresses ipa_sym_addrs; | 223 static struct ipa_sym_addresses ipa_sym_addrs; |
| 232 | |
| 233 int all_tracepoint_symbols_looked_up; | |
| 234 | |
| 235 int | |
| 236 in_process_agent_loaded (void) | |
| 237 { | |
| 238 return all_tracepoint_symbols_looked_up; | |
| 239 } | |
| 240 | 224 |
| 241 static int read_inferior_integer (CORE_ADDR symaddr, int *val); | 225 static int read_inferior_integer (CORE_ADDR symaddr, int *val); |
| 242 | 226 |
| 243 /* Returns true if both the in-process agent library and the static | 227 /* Returns true if both the in-process agent library and the static |
| 244 tracepoints libraries are loaded in the inferior. */ | 228 tracepoints libraries are loaded in the inferior, and agent has |
| 229 capability on static tracepoints. */ |
| 245 | 230 |
| 246 static int | 231 static int |
| 247 in_process_agent_loaded_ust (void) | 232 in_process_agent_supports_ust (void) |
| 248 { | 233 { |
| 249 int loaded = 0; | 234 int loaded = 0; |
| 250 | 235 |
| 251 if (!in_process_agent_loaded ()) | 236 if (!agent_loaded_p ()) |
| 252 { | 237 { |
| 253 warning ("In-process agent not loaded"); | 238 warning ("In-process agent not loaded"); |
| 254 return 0; | 239 return 0; |
| 255 } | 240 } |
| 256 | 241 |
| 257 if (read_inferior_integer (ipa_sym_addrs.addr_ust_loaded, &loaded)) | 242 if (agent_capability_check (AGENT_CAPA_STATIC_TRACE)) |
| 258 { | 243 { |
| 259 warning ("Error reading ust_loaded in lib"); | 244 /* Agent understands static tracepoint, then check whether UST is in |
| 260 return 0; | 245 » fact loaded in the inferior. */ |
| 246 if (read_inferior_integer (ipa_sym_addrs.addr_ust_loaded, &loaded)) |
| 247 » { |
| 248 » warning ("Error reading ust_loaded in lib"); |
| 249 » return 0; |
| 250 » } |
| 251 |
| 252 return loaded; |
| 261 } | 253 } |
| 262 | 254 else |
| 263 return loaded; | 255 return 0; |
| 264 } | 256 } |
| 265 | 257 |
| 266 static void | 258 static void |
| 267 write_e_ipa_not_loaded (char *buffer) | 259 write_e_ipa_not_loaded (char *buffer) |
| 268 { | 260 { |
| 269 sprintf (buffer, | 261 sprintf (buffer, |
| 270 "E.In-process agent library not loaded in process. " | 262 "E.In-process agent library not loaded in process. " |
| 271 "Fast and static tracepoints unavailable."); | 263 "Fast and static tracepoints unavailable."); |
| 272 } | 264 } |
| 273 | 265 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 285 sprintf (buffer, "E.GDBserver was built without static tracepoints support"); | 277 sprintf (buffer, "E.GDBserver was built without static tracepoints support"); |
| 286 #endif | 278 #endif |
| 287 } | 279 } |
| 288 | 280 |
| 289 /* If the in-process agent library isn't loaded in the inferior, write | 281 /* If the in-process agent library isn't loaded in the inferior, write |
| 290 an error to BUFFER, and return 1. Otherwise, return 0. */ | 282 an error to BUFFER, and return 1. Otherwise, return 0. */ |
| 291 | 283 |
| 292 static int | 284 static int |
| 293 maybe_write_ipa_not_loaded (char *buffer) | 285 maybe_write_ipa_not_loaded (char *buffer) |
| 294 { | 286 { |
| 295 if (!in_process_agent_loaded ()) | 287 if (!agent_loaded_p ()) |
| 296 { | 288 { |
| 297 write_e_ipa_not_loaded (buffer); | 289 write_e_ipa_not_loaded (buffer); |
| 298 return 1; | 290 return 1; |
| 299 } | 291 } |
| 300 return 0; | 292 return 0; |
| 301 } | 293 } |
| 302 | 294 |
| 303 /* If the in-process agent library and the ust (static tracepoints) | 295 /* If the in-process agent library and the ust (static tracepoints) |
| 304 library aren't loaded in the inferior, write an error to BUFFER, | 296 library aren't loaded in the inferior, write an error to BUFFER, |
| 305 and return 1. Otherwise, return 0. */ | 297 and return 1. Otherwise, return 0. */ |
| 306 | 298 |
| 307 static int | 299 static int |
| 308 maybe_write_ipa_ust_not_loaded (char *buffer) | 300 maybe_write_ipa_ust_not_loaded (char *buffer) |
| 309 { | 301 { |
| 310 if (!in_process_agent_loaded ()) | 302 if (!agent_loaded_p ()) |
| 311 { | 303 { |
| 312 write_e_ipa_not_loaded (buffer); | 304 write_e_ipa_not_loaded (buffer); |
| 313 return 1; | 305 return 1; |
| 314 } | 306 } |
| 315 else if (!in_process_agent_loaded_ust ()) | 307 else if (!in_process_agent_supports_ust ()) |
| 316 { | 308 { |
| 317 write_e_ust_not_loaded (buffer); | 309 write_e_ust_not_loaded (buffer); |
| 318 return 1; | 310 return 1; |
| 319 } | 311 } |
| 320 return 0; | 312 return 0; |
| 321 } | 313 } |
| 322 | 314 |
| 323 /* Cache all future symbols that the tracepoints module might request. | 315 /* Cache all future symbols that the tracepoints module might request. |
| 324 We can not request symbols at arbitrary states in the remote | 316 We can not request symbols at arbitrary states in the remote |
| 325 protocol, only when the client tells us that new symbols are | 317 protocol, only when the client tells us that new symbols are |
| 326 available. So when we load the in-process library, make sure to | 318 available. So when we load the in-process library, make sure to |
| 327 check the entire list. */ | 319 check the entire list. */ |
| 328 | 320 |
| 329 void | 321 void |
| 330 tracepoint_look_up_symbols (void) | 322 tracepoint_look_up_symbols (void) |
| 331 { | 323 { |
| 332 int i; | 324 int i; |
| 333 | 325 |
| 334 if (all_tracepoint_symbols_looked_up) | 326 if (agent_loaded_p ()) |
| 335 return; | 327 return; |
| 336 | 328 |
| 337 for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++) | 329 for (i = 0; i < sizeof (symbol_list) / sizeof (symbol_list[0]); i++) |
| 338 { | 330 { |
| 339 CORE_ADDR *addrp = | 331 CORE_ADDR *addrp = |
| 340 (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset); | 332 (CORE_ADDR *) ((char *) &ipa_sym_addrs + symbol_list[i].offset); |
| 341 | 333 |
| 342 if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0) | 334 if (look_up_one_symbol (symbol_list[i].name, addrp, 1) == 0) |
| 343 { | 335 { |
| 344 if (debug_threads) | 336 if (debug_threads) |
| 345 fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name); | 337 fprintf (stderr, "symbol `%s' not found\n", symbol_list[i].name); |
| 346 return; | 338 return; |
| 347 } | 339 } |
| 348 } | 340 } |
| 349 | 341 |
| 350 all_tracepoint_symbols_looked_up = 1; | 342 agent_look_up_symbols (NULL); |
| 351 } | 343 } |
| 352 | 344 |
| 353 #endif | 345 #endif |
| 354 | 346 |
| 355 /* GDBserver places a breakpoint on the IPA's version (which is a nop) | 347 /* GDBserver places a breakpoint on the IPA's version (which is a nop) |
| 356 of the "stop_tracing" function. When this breakpoint is hit, | 348 of the "stop_tracing" function. When this breakpoint is hit, |
| 357 tracing stopped in the IPA for some reason. E.g., due to | 349 tracing stopped in the IPA for some reason. E.g., due to |
| 358 tracepoint reaching the pass count, hitting conditional expression | 350 tracepoint reaching the pass count, hitting conditional expression |
| 359 evaluation error, etc. | 351 evaluation error, etc. |
| 360 | 352 |
| 361 The IPA's trace buffer is never in circular tracing mode: instead, | 353 The IPA's trace buffer is never in circular tracing mode: instead, |
| 362 GDBserver's is, and whenever the in-process buffer fills, it calls | 354 GDBserver's is, and whenever the in-process buffer fills, it calls |
| 363 "flush_trace_buffer", which triggers an internal breakpoint. | 355 "flush_trace_buffer", which triggers an internal breakpoint. |
| 364 GDBserver reacts to this breakpoint by pulling the meanwhile | 356 GDBserver reacts to this breakpoint by pulling the meanwhile |
| 365 collected data. Old frames discarding is always handled on the | 357 collected data. Old frames discarding is always handled on the |
| 366 GDBserver side. */ | 358 GDBserver side. */ |
| 367 | 359 |
| 368 #ifdef IN_PROCESS_AGENT | 360 #ifdef IN_PROCESS_AGENT |
| 369 int debug_threads = 0; | |
| 370 | |
| 371 int | 361 int |
| 372 read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) | 362 read_inferior_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len) |
| 373 { | 363 { |
| 374 memcpy (myaddr, (void *) (uintptr_t) memaddr, len); | 364 memcpy (myaddr, (void *) (uintptr_t) memaddr, len); |
| 375 return 0; | 365 return 0; |
| 376 } | 366 } |
| 377 | 367 |
| 378 /* Call this in the functions where GDBserver places a breakpoint, so | 368 /* Call this in the functions where GDBserver places a breakpoint, so |
| 379 that the compiler doesn't try to be clever and skip calling the | 369 that the compiler doesn't try to be clever and skip calling the |
| 380 function at all. This is necessary, even if we tell the compiler | 370 function at all. This is necessary, even if we tell the compiler |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 } | 402 } |
| 413 | 403 |
| 414 /* Breakpoint at "stop_tracing" in the inferior lib. */ | 404 /* Breakpoint at "stop_tracing" in the inferior lib. */ |
| 415 struct breakpoint *stop_tracing_bkpt; | 405 struct breakpoint *stop_tracing_bkpt; |
| 416 static int stop_tracing_handler (CORE_ADDR); | 406 static int stop_tracing_handler (CORE_ADDR); |
| 417 | 407 |
| 418 /* Breakpoint at "flush_trace_buffer" in the inferior lib. */ | 408 /* Breakpoint at "flush_trace_buffer" in the inferior lib. */ |
| 419 struct breakpoint *flush_trace_buffer_bkpt; | 409 struct breakpoint *flush_trace_buffer_bkpt; |
| 420 static int flush_trace_buffer_handler (CORE_ADDR); | 410 static int flush_trace_buffer_handler (CORE_ADDR); |
| 421 | 411 |
| 422 static void download_tracepoints (void); | |
| 423 static void download_trace_state_variables (void); | 412 static void download_trace_state_variables (void); |
| 424 static void upload_fast_traceframes (void); | 413 static void upload_fast_traceframes (void); |
| 425 | 414 |
| 426 static int run_inferior_command (char *cmd); | 415 static int run_inferior_command (char *cmd, int len); |
| 427 | 416 |
| 428 static int | 417 static int |
| 429 read_inferior_integer (CORE_ADDR symaddr, int *val) | 418 read_inferior_integer (CORE_ADDR symaddr, int *val) |
| 430 { | 419 { |
| 431 return read_inferior_memory (symaddr, (unsigned char *) val, | 420 return read_inferior_memory (symaddr, (unsigned char *) val, |
| 432 sizeof (*val)); | 421 sizeof (*val)); |
| 433 } | 422 } |
| 434 | 423 |
| 424 struct tracepoint; |
| 425 static int tracepoint_send_agent (struct tracepoint *tpoint); |
| 426 |
| 435 static int | 427 static int |
| 436 read_inferior_uinteger (CORE_ADDR symaddr, unsigned int *val) | 428 read_inferior_uinteger (CORE_ADDR symaddr, unsigned int *val) |
| 437 { | 429 { |
| 438 return read_inferior_memory (symaddr, (unsigned char *) val, | 430 return read_inferior_memory (symaddr, (unsigned char *) val, |
| 439 sizeof (*val)); | 431 sizeof (*val)); |
| 440 } | 432 } |
| 441 | 433 |
| 442 static int | 434 static int |
| 443 read_inferior_data_pointer (CORE_ADDR symaddr, CORE_ADDR *val) | 435 read_inferior_data_pointer (CORE_ADDR symaddr, CORE_ADDR *val) |
| 444 { | 436 { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 463 { | 455 { |
| 464 return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); | 456 return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); |
| 465 } | 457 } |
| 466 | 458 |
| 467 static int | 459 static int |
| 468 write_inferior_uinteger (CORE_ADDR symaddr, unsigned int val) | 460 write_inferior_uinteger (CORE_ADDR symaddr, unsigned int val) |
| 469 { | 461 { |
| 470 return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); | 462 return write_inferior_memory (symaddr, (unsigned char *) &val, sizeof (val)); |
| 471 } | 463 } |
| 472 | 464 |
| 465 static CORE_ADDR target_malloc (ULONGEST size); |
| 466 static int write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr); |
| 467 |
| 468 #define COPY_FIELD_TO_BUF(BUF, OBJ, FIELD) \ |
| 469 do { \ |
| 470 memcpy (BUF, &(OBJ)->FIELD, sizeof ((OBJ)->FIELD)); \ |
| 471 BUF += sizeof ((OBJ)->FIELD); \ |
| 472 } while (0) |
| 473 |
| 473 #endif | 474 #endif |
| 474 | 475 |
| 475 /* This enum must exactly match what is documented in | 476 /* Operations on various types of tracepoint actions. */ |
| 476 gdb/doc/agentexpr.texi, including all the numerical values. */ | |
| 477 | 477 |
| 478 enum gdb_agent_op | 478 struct tracepoint_action; |
| 479 { | |
| 480 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) \ | |
| 481 gdb_agent_op_ ## NAME = VALUE, | |
| 482 #include "ax.def" | |
| 483 #undef DEFOP | |
| 484 gdb_agent_op_last | |
| 485 }; | |
| 486 | 479 |
| 487 static const char *gdb_agent_op_names [gdb_agent_op_last] = | 480 struct tracepoint_action_ops |
| 488 { | 481 { |
| 489 "?undef?" | 482 /* Download tracepoint action ACTION to IPA. Return the address of action |
| 490 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , # NAME | 483 in IPA/inferior. */ |
| 491 #include "ax.def" | 484 CORE_ADDR (*download) (const struct tracepoint_action *action); |
| 492 #undef DEFOP | |
| 493 }; | |
| 494 | 485 |
| 495 static const unsigned char gdb_agent_op_sizes [gdb_agent_op_last] = | 486 /* Send ACTION to agent via command buffer started from BUFFER. Return |
| 496 { | 487 updated head of command buffer. */ |
| 497 0 | 488 char* (*send) (char *buffer, const struct tracepoint_action *action); |
| 498 #define DEFOP(NAME, SIZE, DATA_SIZE, CONSUMED, PRODUCED, VALUE) , SIZE | |
| 499 #include "ax.def" | |
| 500 #undef DEFOP | |
| 501 }; | |
| 502 | |
| 503 struct agent_expr | |
| 504 { | |
| 505 int length; | |
| 506 | |
| 507 unsigned char *bytes; | |
| 508 }; | 489 }; |
| 509 | 490 |
| 510 /* Base action. Concrete actions inherit this. */ | 491 /* Base action. Concrete actions inherit this. */ |
| 511 | 492 |
| 512 struct tracepoint_action | 493 struct tracepoint_action |
| 513 { | 494 { |
| 495 #ifndef IN_PROCESS_AGENT |
| 496 const struct tracepoint_action_ops *ops; |
| 497 #endif |
| 514 char type; | 498 char type; |
| 515 }; | 499 }; |
| 516 | 500 |
| 517 /* An 'M' (collect memory) action. */ | 501 /* An 'M' (collect memory) action. */ |
| 518 struct collect_memory_action | 502 struct collect_memory_action |
| 519 { | 503 { |
| 520 struct tracepoint_action base; | 504 struct tracepoint_action base; |
| 521 | 505 |
| 522 ULONGEST addr; | 506 ULONGEST addr; |
| 523 ULONGEST len; | 507 ULONGEST len; |
| 524 int basereg; | 508 int32_t basereg; |
| 525 }; | 509 }; |
| 526 | 510 |
| 527 /* An 'R' (collect registers) action. */ | 511 /* An 'R' (collect registers) action. */ |
| 528 | 512 |
| 529 struct collect_registers_action | 513 struct collect_registers_action |
| 530 { | 514 { |
| 531 struct tracepoint_action base; | 515 struct tracepoint_action base; |
| 532 }; | 516 }; |
| 533 | 517 |
| 534 /* An 'X' (evaluate expression) action. */ | 518 /* An 'X' (evaluate expression) action. */ |
| 535 | 519 |
| 536 struct eval_expr_action | 520 struct eval_expr_action |
| 537 { | 521 { |
| 538 struct tracepoint_action base; | 522 struct tracepoint_action base; |
| 539 | 523 |
| 540 struct agent_expr *expr; | 524 struct agent_expr *expr; |
| 541 }; | 525 }; |
| 542 | 526 |
| 543 /* An 'L' (collect static trace data) action. */ | 527 /* An 'L' (collect static trace data) action. */ |
| 544 struct collect_static_trace_data_action | 528 struct collect_static_trace_data_action |
| 545 { | 529 { |
| 546 struct tracepoint_action base; | 530 struct tracepoint_action base; |
| 547 }; | 531 }; |
| 548 | 532 |
| 533 #ifndef IN_PROCESS_AGENT |
| 534 static CORE_ADDR |
| 535 m_tracepoint_action_download (const struct tracepoint_action *action) |
| 536 { |
| 537 int size_in_ipa = (sizeof (struct collect_memory_action) |
| 538 - offsetof (struct tracepoint_action, type)); |
| 539 CORE_ADDR ipa_action = target_malloc (size_in_ipa); |
| 540 |
| 541 write_inferior_memory (ipa_action, (unsigned char *) &action->type, |
| 542 size_in_ipa); |
| 543 |
| 544 return ipa_action; |
| 545 } |
| 546 static char * |
| 547 m_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) |
| 548 { |
| 549 struct collect_memory_action *maction |
| 550 = (struct collect_memory_action *) action; |
| 551 |
| 552 COPY_FIELD_TO_BUF (buffer, maction, addr); |
| 553 COPY_FIELD_TO_BUF (buffer, maction, len); |
| 554 COPY_FIELD_TO_BUF (buffer, maction, basereg); |
| 555 |
| 556 return buffer; |
| 557 } |
| 558 |
| 559 static const struct tracepoint_action_ops m_tracepoint_action_ops = |
| 560 { |
| 561 m_tracepoint_action_download, |
| 562 m_tracepoint_action_send, |
| 563 }; |
| 564 |
| 565 static CORE_ADDR |
| 566 r_tracepoint_action_download (const struct tracepoint_action *action) |
| 567 { |
| 568 int size_in_ipa = (sizeof (struct collect_registers_action) |
| 569 - offsetof (struct tracepoint_action, type)); |
| 570 CORE_ADDR ipa_action = target_malloc (size_in_ipa); |
| 571 |
| 572 write_inferior_memory (ipa_action, (unsigned char *) &action->type, |
| 573 size_in_ipa); |
| 574 |
| 575 return ipa_action; |
| 576 } |
| 577 |
| 578 static char * |
| 579 r_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) |
| 580 { |
| 581 return buffer; |
| 582 } |
| 583 |
| 584 static const struct tracepoint_action_ops r_tracepoint_action_ops = |
| 585 { |
| 586 r_tracepoint_action_download, |
| 587 r_tracepoint_action_send, |
| 588 }; |
| 589 |
| 590 static CORE_ADDR download_agent_expr (struct agent_expr *expr); |
| 591 |
| 592 static CORE_ADDR |
| 593 x_tracepoint_action_download (const struct tracepoint_action *action) |
| 594 { |
| 595 int size_in_ipa = (sizeof (struct eval_expr_action) |
| 596 - offsetof (struct tracepoint_action, type)); |
| 597 CORE_ADDR ipa_action = target_malloc (size_in_ipa); |
| 598 CORE_ADDR expr; |
| 599 |
| 600 write_inferior_memory (ipa_action, (unsigned char *) &action->type, |
| 601 size_in_ipa); |
| 602 expr = download_agent_expr (((struct eval_expr_action *)action)->expr); |
| 603 write_inferior_data_ptr (ipa_action + offsetof (struct eval_expr_action, expr) |
| 604 - offsetof (struct tracepoint_action, type), |
| 605 expr); |
| 606 |
| 607 return ipa_action; |
| 608 } |
| 609 |
| 610 /* Copy agent expression AEXPR to buffer pointed by P. If AEXPR is NULL, |
| 611 copy 0 to P. Return updated header of buffer. */ |
| 612 |
| 613 static char * |
| 614 agent_expr_send (char *p, const struct agent_expr *aexpr) |
| 615 { |
| 616 /* Copy the length of condition first, and then copy its |
| 617 content. */ |
| 618 if (aexpr == NULL) |
| 619 { |
| 620 memset (p, 0, 4); |
| 621 p += 4; |
| 622 } |
| 623 else |
| 624 { |
| 625 memcpy (p, &aexpr->length, 4); |
| 626 p +=4; |
| 627 |
| 628 memcpy (p, aexpr->bytes, aexpr->length); |
| 629 p += aexpr->length; |
| 630 } |
| 631 return p; |
| 632 } |
| 633 |
| 634 static char * |
| 635 x_tracepoint_action_send ( char *buffer, const struct tracepoint_action *action) |
| 636 { |
| 637 struct eval_expr_action *eaction = (struct eval_expr_action *) action; |
| 638 |
| 639 return agent_expr_send (buffer, eaction->expr); |
| 640 } |
| 641 |
| 642 static const struct tracepoint_action_ops x_tracepoint_action_ops = |
| 643 { |
| 644 x_tracepoint_action_download, |
| 645 x_tracepoint_action_send, |
| 646 }; |
| 647 |
| 648 static CORE_ADDR |
| 649 l_tracepoint_action_download (const struct tracepoint_action *action) |
| 650 { |
| 651 int size_in_ipa = (sizeof (struct collect_static_trace_data_action) |
| 652 - offsetof (struct tracepoint_action, type)); |
| 653 CORE_ADDR ipa_action = target_malloc (size_in_ipa); |
| 654 |
| 655 write_inferior_memory (ipa_action, (unsigned char *) &action->type, |
| 656 size_in_ipa); |
| 657 |
| 658 return ipa_action; |
| 659 } |
| 660 |
| 661 static char * |
| 662 l_tracepoint_action_send (char *buffer, const struct tracepoint_action *action) |
| 663 { |
| 664 return buffer; |
| 665 } |
| 666 |
| 667 static const struct tracepoint_action_ops l_tracepoint_action_ops = |
| 668 { |
| 669 l_tracepoint_action_download, |
| 670 l_tracepoint_action_send, |
| 671 }; |
| 672 #endif |
| 673 |
| 549 /* This structure describes a piece of the source-level definition of | 674 /* This structure describes a piece of the source-level definition of |
| 550 the tracepoint. The contents are not interpreted by the target, | 675 the tracepoint. The contents are not interpreted by the target, |
| 551 but preserved verbatim for uploading upon reconnection. */ | 676 but preserved verbatim for uploading upon reconnection. */ |
| 552 | 677 |
| 553 struct source_string | 678 struct source_string |
| 554 { | 679 { |
| 555 /* The type of string, such as "cond" for a conditional. */ | 680 /* The type of string, such as "cond" for a conditional. */ |
| 556 char *type; | 681 char *type; |
| 557 | 682 |
| 558 /* The source-level string itself. For the sake of target | 683 /* The source-level string itself. For the sake of target |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 location. Our target version of tracepoints is more like GDB's | 718 location. Our target version of tracepoints is more like GDB's |
| 594 notion of "breakpoint locations", but we have almost nothing that | 719 notion of "breakpoint locations", but we have almost nothing that |
| 595 is not per-location, so we bother having two kinds of objects. The | 720 is not per-location, so we bother having two kinds of objects. The |
| 596 key consequence is that numbers are not unique, and that it takes | 721 key consequence is that numbers are not unique, and that it takes |
| 597 both number and address to identify a tracepoint uniquely. */ | 722 both number and address to identify a tracepoint uniquely. */ |
| 598 | 723 |
| 599 struct tracepoint | 724 struct tracepoint |
| 600 { | 725 { |
| 601 /* The number of the tracepoint, as specified by GDB. Several | 726 /* The number of the tracepoint, as specified by GDB. Several |
| 602 tracepoint objects here may share a number. */ | 727 tracepoint objects here may share a number. */ |
| 603 int number; | 728 uint32_t number; |
| 604 | 729 |
| 605 /* Address at which the tracepoint is supposed to trigger. Several | 730 /* Address at which the tracepoint is supposed to trigger. Several |
| 606 tracepoints may share an address. */ | 731 tracepoints may share an address. */ |
| 607 CORE_ADDR address; | 732 CORE_ADDR address; |
| 608 | 733 |
| 609 /* Tracepoint type. */ | 734 /* Tracepoint type. */ |
| 610 enum tracepoint_type type; | 735 enum tracepoint_type type; |
| 611 | 736 |
| 612 /* True if the tracepoint is currently enabled. */ | 737 /* True if the tracepoint is currently enabled. */ |
| 613 int enabled; | 738 int8_t enabled; |
| 614 | 739 |
| 615 /* The number of single steps that will be performed after each | 740 /* The number of single steps that will be performed after each |
| 616 tracepoint hit. */ | 741 tracepoint hit. */ |
| 617 long step_count; | 742 uint64_t step_count; |
| 618 | 743 |
| 619 /* The number of times the tracepoint may be hit before it will | 744 /* The number of times the tracepoint may be hit before it will |
| 620 terminate the entire tracing run. */ | 745 terminate the entire tracing run. */ |
| 621 long pass_count; | 746 uint64_t pass_count; |
| 622 | 747 |
| 623 /* Pointer to the agent expression that is the tracepoint's | 748 /* Pointer to the agent expression that is the tracepoint's |
| 624 conditional, or NULL if the tracepoint is unconditional. */ | 749 conditional, or NULL if the tracepoint is unconditional. */ |
| 625 struct agent_expr *cond; | 750 struct agent_expr *cond; |
| 626 | 751 |
| 627 /* The list of actions to take when the tracepoint triggers. */ | 752 /* The list of actions to take when the tracepoint triggers. */ |
| 628 int numactions; | 753 uint32_t numactions; |
| 629 struct tracepoint_action **actions; | 754 struct tracepoint_action **actions; |
| 630 | 755 |
| 631 /* Count of the times we've hit this tracepoint during the run. | 756 /* Count of the times we've hit this tracepoint during the run. |
| 632 Note that while-stepping steps are not counted as "hits". */ | 757 Note that while-stepping steps are not counted as "hits". */ |
| 633 long hit_count; | 758 uint64_t hit_count; |
| 634 | 759 |
| 635 /* Cached sum of the sizes of traceframes created by this point. */ | 760 /* Cached sum of the sizes of traceframes created by this point. */ |
| 636 long traceframe_usage; | 761 uint64_t traceframe_usage; |
| 637 | 762 |
| 638 CORE_ADDR compiled_cond; | 763 CORE_ADDR compiled_cond; |
| 639 | 764 |
| 640 /* Link to the next tracepoint in the list. */ | 765 /* Link to the next tracepoint in the list. */ |
| 641 struct tracepoint *next; | 766 struct tracepoint *next; |
| 642 | 767 |
| 643 #ifndef IN_PROCESS_AGENT | 768 #ifndef IN_PROCESS_AGENT |
| 644 /* The list of actions to take when the tracepoint triggers, in | 769 /* The list of actions to take when the tracepoint triggers, in |
| 645 string/packet form. */ | 770 string/packet form. */ |
| 646 char **actions_str; | 771 char **actions_str; |
| 647 | 772 |
| 648 /* The collection of strings that describe the tracepoint as it was | 773 /* The collection of strings that describe the tracepoint as it was |
| 649 entered into GDB. These are not used by the target, but are | 774 entered into GDB. These are not used by the target, but are |
| 650 reported back to GDB upon reconnection. */ | 775 reported back to GDB upon reconnection. */ |
| 651 struct source_string *source_strings; | 776 struct source_string *source_strings; |
| 652 | 777 |
| 653 /* The number of bytes displaced by fast tracepoints. It may subsume | 778 /* The number of bytes displaced by fast tracepoints. It may subsume |
| 654 multiple instructions, for multi-byte fast tracepoints. This | 779 multiple instructions, for multi-byte fast tracepoints. This |
| 655 field is only valid for fast tracepoints. */ | 780 field is only valid for fast tracepoints. */ |
| 656 int orig_size; | 781 uint32_t orig_size; |
| 657 | 782 |
| 658 /* Only for fast tracepoints. */ | 783 /* Only for fast tracepoints. */ |
| 659 CORE_ADDR obj_addr_on_target; | 784 CORE_ADDR obj_addr_on_target; |
| 660 | 785 |
| 661 /* Address range where the original instruction under a fast | 786 /* Address range where the original instruction under a fast |
| 662 tracepoint was relocated to. (_end is actually one byte past | 787 tracepoint was relocated to. (_end is actually one byte past |
| 663 the end). */ | 788 the end). */ |
| 664 CORE_ADDR adjusted_insn_addr; | 789 CORE_ADDR adjusted_insn_addr; |
| 665 CORE_ADDR adjusted_insn_addr_end; | 790 CORE_ADDR adjusted_insn_addr_end; |
| 666 | 791 |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 #endif | 856 #endif |
| 732 | 857 |
| 733 /* The first tracepoint to exceed its pass count. */ | 858 /* The first tracepoint to exceed its pass count. */ |
| 734 | 859 |
| 735 IP_AGENT_EXPORT struct tracepoint *stopping_tracepoint; | 860 IP_AGENT_EXPORT struct tracepoint *stopping_tracepoint; |
| 736 | 861 |
| 737 /* True if the trace buffer is full or otherwise no longer usable. */ | 862 /* True if the trace buffer is full or otherwise no longer usable. */ |
| 738 | 863 |
| 739 IP_AGENT_EXPORT int trace_buffer_is_full; | 864 IP_AGENT_EXPORT int trace_buffer_is_full; |
| 740 | 865 |
| 741 /* Enumeration of the different kinds of things that can happen during | |
| 742 agent expression evaluation. */ | |
| 743 | |
| 744 enum eval_result_type | |
| 745 { | |
| 746 expr_eval_no_error, | |
| 747 expr_eval_empty_expression, | |
| 748 expr_eval_empty_stack, | |
| 749 expr_eval_stack_overflow, | |
| 750 expr_eval_stack_underflow, | |
| 751 expr_eval_unhandled_opcode, | |
| 752 expr_eval_unrecognized_opcode, | |
| 753 expr_eval_divide_by_zero, | |
| 754 expr_eval_invalid_goto | |
| 755 }; | |
| 756 | |
| 757 static enum eval_result_type expr_eval_result = expr_eval_no_error; | 866 static enum eval_result_type expr_eval_result = expr_eval_no_error; |
| 758 | 867 |
| 759 #ifndef IN_PROCESS_AGENT | 868 #ifndef IN_PROCESS_AGENT |
| 760 | 869 |
| 761 static const char *eval_result_names[] = | 870 static const char *eval_result_names[] = |
| 762 { | 871 { |
| 763 "terror:in the attic", /* this should never be reported */ | 872 "terror:in the attic", /* this should never be reported */ |
| 764 "terror:empty expression", | 873 "terror:empty expression", |
| 765 "terror:empty stack", | 874 "terror:empty stack", |
| 766 "terror:stack overflow", | 875 "terror:stack overflow", |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1230 collect_data_at_tracepoint. */ | 1339 collect_data_at_tracepoint. */ |
| 1231 struct trap_tracepoint_ctx | 1340 struct trap_tracepoint_ctx |
| 1232 { | 1341 { |
| 1233 struct tracepoint_hit_ctx base; | 1342 struct tracepoint_hit_ctx base; |
| 1234 | 1343 |
| 1235 struct regcache *regcache; | 1344 struct regcache *regcache; |
| 1236 }; | 1345 }; |
| 1237 | 1346 |
| 1238 #endif | 1347 #endif |
| 1239 | 1348 |
| 1240 #ifndef IN_PROCESS_AGENT | 1349 static enum eval_result_type |
| 1241 static struct agent_expr *parse_agent_expr (char **actparm); | 1350 eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx, |
| 1242 static char *unparse_agent_expr (struct agent_expr *aexpr); | 1351 » » » struct traceframe *tframe, |
| 1243 #endif | 1352 » » » struct agent_expr *aexpr, |
| 1244 static enum eval_result_type eval_agent_expr (struct tracepoint_hit_ctx *ctx, | 1353 » » » ULONGEST *rslt); |
| 1245 » » » » » struct traceframe *tframe, | |
| 1246 » » » » » struct agent_expr *aexpr, | |
| 1247 » » » » » ULONGEST *rslt); | |
| 1248 | |
| 1249 static int agent_mem_read (struct traceframe *tframe, | |
| 1250 » » » unsigned char *to, CORE_ADDR from, ULONGEST len); | |
| 1251 static int agent_mem_read_string (struct traceframe *tframe, | |
| 1252 » » » » unsigned char *to, CORE_ADDR from, | |
| 1253 » » » » ULONGEST len); | |
| 1254 static int agent_tsv_read (struct traceframe *tframe, int n); | |
| 1255 | 1354 |
| 1256 #ifndef IN_PROCESS_AGENT | 1355 #ifndef IN_PROCESS_AGENT |
| 1257 static CORE_ADDR traceframe_get_pc (struct traceframe *tframe); | 1356 static CORE_ADDR traceframe_get_pc (struct traceframe *tframe); |
| 1258 static int traceframe_read_tsv (int num, LONGEST *val); | 1357 static int traceframe_read_tsv (int num, LONGEST *val); |
| 1259 #endif | 1358 #endif |
| 1260 | 1359 |
| 1261 static int condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx, | 1360 static int condition_true_at_tracepoint (struct tracepoint_hit_ctx *ctx, |
| 1262 struct tracepoint *tpoint); | 1361 struct tracepoint *tpoint); |
| 1263 | 1362 |
| 1264 #ifndef IN_PROCESS_AGENT | 1363 #ifndef IN_PROCESS_AGENT |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1281 struct tracepoint *tpoint, | 1380 struct tracepoint *tpoint, |
| 1282 struct traceframe *tframe, | 1381 struct traceframe *tframe, |
| 1283 struct tracepoint_action *taction); | 1382 struct tracepoint_action *taction); |
| 1284 | 1383 |
| 1285 #ifndef IN_PROCESS_AGENT | 1384 #ifndef IN_PROCESS_AGENT |
| 1286 static struct tracepoint *fast_tracepoint_from_ipa_tpoint_address (CORE_ADDR); | 1385 static struct tracepoint *fast_tracepoint_from_ipa_tpoint_address (CORE_ADDR); |
| 1287 | 1386 |
| 1288 static void install_tracepoint (struct tracepoint *, char *own_buf); | 1387 static void install_tracepoint (struct tracepoint *, char *own_buf); |
| 1289 static void download_tracepoint (struct tracepoint *); | 1388 static void download_tracepoint (struct tracepoint *); |
| 1290 static int install_fast_tracepoint (struct tracepoint *, char *errbuf); | 1389 static int install_fast_tracepoint (struct tracepoint *, char *errbuf); |
| 1390 static void clone_fast_tracepoint (struct tracepoint *to, |
| 1391 const struct tracepoint *from); |
| 1291 #endif | 1392 #endif |
| 1292 | 1393 |
| 1293 static LONGEST get_timestamp (void); | 1394 static LONGEST get_timestamp (void); |
| 1294 | 1395 |
| 1295 #if defined(__GNUC__) | 1396 #if defined(__GNUC__) |
| 1296 # define memory_barrier() asm volatile ("" : : : "memory") | 1397 # define memory_barrier() asm volatile ("" : : : "memory") |
| 1297 #else | 1398 #else |
| 1298 # define memory_barrier() do {} while (0) | 1399 # define memory_barrier() do {} while (0) |
| 1299 #endif | 1400 #endif |
| 1300 | 1401 |
| 1301 /* We only build the IPA if this builtin is supported, and there are | 1402 /* We only build the IPA if this builtin is supported, and there are |
| 1302 no uses of this in GDBserver itself, so we're safe in defining this | 1403 no uses of this in GDBserver itself, so we're safe in defining this |
| 1303 unconditionally. */ | 1404 unconditionally. */ |
| 1304 #define cmpxchg(mem, oldval, newval) \ | 1405 #define cmpxchg(mem, oldval, newval) \ |
| 1305 __sync_val_compare_and_swap (mem, oldval, newval) | 1406 __sync_val_compare_and_swap (mem, oldval, newval) |
| 1306 | 1407 |
| 1307 /* The size in bytes of the buffer used to talk to the IPA helper | |
| 1308 thread. */ | |
| 1309 #define CMD_BUF_SIZE 1024 | |
| 1310 | |
| 1311 /* Record that an error occurred during expression evaluation. */ | 1408 /* Record that an error occurred during expression evaluation. */ |
| 1312 | 1409 |
| 1313 static void | 1410 static void |
| 1314 record_tracepoint_error (struct tracepoint *tpoint, const char *which, | 1411 record_tracepoint_error (struct tracepoint *tpoint, const char *which, |
| 1315 enum eval_result_type rtype) | 1412 enum eval_result_type rtype) |
| 1316 { | 1413 { |
| 1317 trace_debug ("Tracepoint %d at %s %s eval reports error %d", | 1414 trace_debug ("Tracepoint %d at %s %s eval reports error %d", |
| 1318 tpoint->number, paddress (tpoint->address), which, rtype); | 1415 tpoint->number, paddress (tpoint->address), which, rtype); |
| 1319 | 1416 |
| 1320 #ifdef IN_PROCESS_AGENT | 1417 #ifdef IN_PROCESS_AGENT |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1753 { | 1850 { |
| 1754 struct tracepoint *tpoint; | 1851 struct tracepoint *tpoint; |
| 1755 | 1852 |
| 1756 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) | 1853 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) |
| 1757 if (tpoint->number == id && tpoint->address == addr) | 1854 if (tpoint->number == id && tpoint->address == addr) |
| 1758 return tpoint; | 1855 return tpoint; |
| 1759 | 1856 |
| 1760 return NULL; | 1857 return NULL; |
| 1761 } | 1858 } |
| 1762 | 1859 |
| 1860 /* Remove TPOINT from global list. */ |
| 1861 |
| 1862 static void |
| 1863 remove_tracepoint (struct tracepoint *tpoint) |
| 1864 { |
| 1865 struct tracepoint *tp, *tp_prev; |
| 1866 |
| 1867 for (tp = tracepoints, tp_prev = NULL; tp && tp != tpoint; |
| 1868 tp_prev = tp, tp = tp->next) |
| 1869 ; |
| 1870 |
| 1871 if (tp) |
| 1872 { |
| 1873 if (tp_prev) |
| 1874 tp_prev->next = tp->next; |
| 1875 else |
| 1876 tracepoints = tp->next; |
| 1877 |
| 1878 xfree (tp); |
| 1879 } |
| 1880 } |
| 1881 |
| 1763 /* There may be several tracepoints with the same number (because they | 1882 /* There may be several tracepoints with the same number (because they |
| 1764 are "locations", in GDB parlance); return the next one after the | 1883 are "locations", in GDB parlance); return the next one after the |
| 1765 given tracepoint, or search from the beginning of the list if the | 1884 given tracepoint, or search from the beginning of the list if the |
| 1766 first argument is NULL. */ | 1885 first argument is NULL. */ |
| 1767 | 1886 |
| 1768 static struct tracepoint * | 1887 static struct tracepoint * |
| 1769 find_next_tracepoint_by_number (struct tracepoint *prev_tp, int num) | 1888 find_next_tracepoint_by_number (struct tracepoint *prev_tp, int num) |
| 1770 { | 1889 { |
| 1771 struct tracepoint *tpoint; | 1890 struct tracepoint *tpoint; |
| 1772 | 1891 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1818 switch (*act) | 1937 switch (*act) |
| 1819 { | 1938 { |
| 1820 case 'M': | 1939 case 'M': |
| 1821 { | 1940 { |
| 1822 struct collect_memory_action *maction; | 1941 struct collect_memory_action *maction; |
| 1823 ULONGEST basereg; | 1942 ULONGEST basereg; |
| 1824 int is_neg; | 1943 int is_neg; |
| 1825 | 1944 |
| 1826 maction = xmalloc (sizeof *maction); | 1945 maction = xmalloc (sizeof *maction); |
| 1827 maction->base.type = *act; | 1946 maction->base.type = *act; |
| 1947 maction->base.ops = &m_tracepoint_action_ops; |
| 1828 action = &maction->base; | 1948 action = &maction->base; |
| 1829 | 1949 |
| 1830 ++act; | 1950 ++act; |
| 1831 is_neg = (*act == '-'); | 1951 is_neg = (*act == '-'); |
| 1832 if (*act == '-') | 1952 if (*act == '-') |
| 1833 ++act; | 1953 ++act; |
| 1834 act = unpack_varlen_hex (act, &basereg); | 1954 act = unpack_varlen_hex (act, &basereg); |
| 1835 ++act; | 1955 ++act; |
| 1836 act = unpack_varlen_hex (act, &maction->addr); | 1956 act = unpack_varlen_hex (act, &maction->addr); |
| 1837 ++act; | 1957 ++act; |
| 1838 act = unpack_varlen_hex (act, &maction->len); | 1958 act = unpack_varlen_hex (act, &maction->len); |
| 1839 maction->basereg = (is_neg | 1959 maction->basereg = (is_neg |
| 1840 ? - (int) basereg | 1960 ? - (int) basereg |
| 1841 : (int) basereg); | 1961 : (int) basereg); |
| 1842 trace_debug ("Want to collect %s bytes at 0x%s (basereg %d)", | 1962 trace_debug ("Want to collect %s bytes at 0x%s (basereg %d)", |
| 1843 pulongest (maction->len), | 1963 pulongest (maction->len), |
| 1844 paddress (maction->addr), maction->basereg); | 1964 paddress (maction->addr), maction->basereg); |
| 1845 break; | 1965 break; |
| 1846 } | 1966 } |
| 1847 case 'R': | 1967 case 'R': |
| 1848 { | 1968 { |
| 1849 struct collect_registers_action *raction; | 1969 struct collect_registers_action *raction; |
| 1850 | 1970 |
| 1851 raction = xmalloc (sizeof *raction); | 1971 raction = xmalloc (sizeof *raction); |
| 1852 raction->base.type = *act; | 1972 raction->base.type = *act; |
| 1973 raction->base.ops = &r_tracepoint_action_ops; |
| 1853 action = &raction->base; | 1974 action = &raction->base; |
| 1854 | 1975 |
| 1855 trace_debug ("Want to collect registers"); | 1976 trace_debug ("Want to collect registers"); |
| 1856 ++act; | 1977 ++act; |
| 1857 /* skip past hex digits of mask for now */ | 1978 /* skip past hex digits of mask for now */ |
| 1858 while (isxdigit(*act)) | 1979 while (isxdigit(*act)) |
| 1859 ++act; | 1980 ++act; |
| 1860 break; | 1981 break; |
| 1861 } | 1982 } |
| 1862 case 'L': | 1983 case 'L': |
| 1863 { | 1984 { |
| 1864 struct collect_static_trace_data_action *raction; | 1985 struct collect_static_trace_data_action *raction; |
| 1865 | 1986 |
| 1866 raction = xmalloc (sizeof *raction); | 1987 raction = xmalloc (sizeof *raction); |
| 1867 raction->base.type = *act; | 1988 raction->base.type = *act; |
| 1989 raction->base.ops = &l_tracepoint_action_ops; |
| 1868 action = &raction->base; | 1990 action = &raction->base; |
| 1869 | 1991 |
| 1870 trace_debug ("Want to collect static trace data"); | 1992 trace_debug ("Want to collect static trace data"); |
| 1871 ++act; | 1993 ++act; |
| 1872 break; | 1994 break; |
| 1873 } | 1995 } |
| 1874 case 'S': | 1996 case 'S': |
| 1875 trace_debug ("Unexpected step action, ignoring"); | 1997 trace_debug ("Unexpected step action, ignoring"); |
| 1876 ++act; | 1998 ++act; |
| 1877 break; | 1999 break; |
| 1878 case 'X': | 2000 case 'X': |
| 1879 { | 2001 { |
| 1880 struct eval_expr_action *xaction; | 2002 struct eval_expr_action *xaction; |
| 1881 | 2003 |
| 1882 xaction = xmalloc (sizeof (*xaction)); | 2004 xaction = xmalloc (sizeof (*xaction)); |
| 1883 xaction->base.type = *act; | 2005 xaction->base.type = *act; |
| 2006 xaction->base.ops = &x_tracepoint_action_ops; |
| 1884 action = &xaction->base; | 2007 action = &xaction->base; |
| 1885 | 2008 |
| 1886 trace_debug ("Want to evaluate expression"); | 2009 trace_debug ("Want to evaluate expression"); |
| 1887 » xaction->expr = parse_agent_expr (&act); | 2010 » xaction->expr = gdb_parse_agent_expr (&act); |
| 1888 break; | 2011 break; |
| 1889 } | 2012 } |
| 1890 default: | 2013 default: |
| 1891 trace_debug ("unknown trace action '%c', ignoring...", *act); | 2014 trace_debug ("unknown trace action '%c', ignoring...", *act); |
| 1892 break; | 2015 break; |
| 1893 case '-': | 2016 case '-': |
| 1894 break; | 2017 break; |
| 1895 } | 2018 } |
| 1896 | 2019 |
| 1897 if (action == NULL) | 2020 if (action == NULL) |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2021 | 2144 |
| 2022 if (!tsv) | 2145 if (!tsv) |
| 2023 { | 2146 { |
| 2024 trace_debug ("No trace state variable %d, skipping value set", num); | 2147 trace_debug ("No trace state variable %d, skipping value set", num); |
| 2025 return; | 2148 return; |
| 2026 } | 2149 } |
| 2027 | 2150 |
| 2028 tsv->value = val; | 2151 tsv->value = val; |
| 2029 } | 2152 } |
| 2030 | 2153 |
| 2154 LONGEST |
| 2155 agent_get_trace_state_variable_value (int num) |
| 2156 { |
| 2157 return get_trace_state_variable_value (num); |
| 2158 } |
| 2159 |
| 2160 void |
| 2161 agent_set_trace_state_variable_value (int num, LONGEST val) |
| 2162 { |
| 2163 set_trace_state_variable_value (num, val); |
| 2164 } |
| 2165 |
| 2031 static void | 2166 static void |
| 2032 set_trace_state_variable_name (int num, const char *name) | 2167 set_trace_state_variable_name (int num, const char *name) |
| 2033 { | 2168 { |
| 2034 struct trace_state_variable *tsv; | 2169 struct trace_state_variable *tsv; |
| 2035 | 2170 |
| 2036 tsv = get_trace_state_variable (num); | 2171 tsv = get_trace_state_variable (num); |
| 2037 | 2172 |
| 2038 if (!tsv) | 2173 if (!tsv) |
| 2039 { | 2174 { |
| 2040 trace_debug ("No trace state variable %d, skipping name set", num); | 2175 trace_debug ("No trace state variable %d, skipping name set", num); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2260 clear_inferior_trace_buffer (); | 2395 clear_inferior_trace_buffer (); |
| 2261 | 2396 |
| 2262 write_ok (packet); | 2397 write_ok (packet); |
| 2263 } | 2398 } |
| 2264 | 2399 |
| 2265 /* Unprobe the UST marker at ADDRESS. */ | 2400 /* Unprobe the UST marker at ADDRESS. */ |
| 2266 | 2401 |
| 2267 static void | 2402 static void |
| 2268 unprobe_marker_at (CORE_ADDR address) | 2403 unprobe_marker_at (CORE_ADDR address) |
| 2269 { | 2404 { |
| 2270 char cmd[CMD_BUF_SIZE]; | 2405 char cmd[IPA_CMD_BUF_SIZE]; |
| 2271 | 2406 |
| 2272 sprintf (cmd, "unprobe_marker_at:%s", paddress (address)); | 2407 sprintf (cmd, "unprobe_marker_at:%s", paddress (address)); |
| 2273 run_inferior_command (cmd); | 2408 run_inferior_command (cmd, strlen (cmd) + 1); |
| 2274 } | 2409 } |
| 2275 | 2410 |
| 2276 /* Restore the program to its pre-tracing state. This routine may be called | 2411 /* Restore the program to its pre-tracing state. This routine may be called |
| 2277 in error situations, so it needs to be careful about only restoring | 2412 in error situations, so it needs to be careful about only restoring |
| 2278 from known-valid bits. */ | 2413 from known-valid bits. */ |
| 2279 | 2414 |
| 2280 static void | 2415 static void |
| 2281 clear_installed_tracepoints (void) | 2416 clear_installed_tracepoints (void) |
| 2282 { | 2417 { |
| 2283 struct tracepoint *tpoint; | 2418 struct tracepoint *tpoint; |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2397 tpoint->orig_size = count; | 2532 tpoint->orig_size = count; |
| 2398 } | 2533 } |
| 2399 else if (*packet == 'S') | 2534 else if (*packet == 'S') |
| 2400 { | 2535 { |
| 2401 tpoint->type = static_tracepoint; | 2536 tpoint->type = static_tracepoint; |
| 2402 ++packet; | 2537 ++packet; |
| 2403 } | 2538 } |
| 2404 else if (*packet == 'X') | 2539 else if (*packet == 'X') |
| 2405 { | 2540 { |
| 2406 actparm = (char *) packet; | 2541 actparm = (char *) packet; |
| 2407 » tpoint->cond = parse_agent_expr (&actparm); | 2542 » tpoint->cond = gdb_parse_agent_expr (&actparm); |
| 2408 packet = actparm; | 2543 packet = actparm; |
| 2409 } | 2544 } |
| 2410 else if (*packet == '-') | 2545 else if (*packet == '-') |
| 2411 break; | 2546 break; |
| 2412 else if (*packet == '\0') | 2547 else if (*packet == '\0') |
| 2413 break; | 2548 break; |
| 2414 else | 2549 else |
| 2415 trace_debug ("Unknown optional tracepoint field"); | 2550 trace_debug ("Unknown optional tracepoint field"); |
| 2416 } | 2551 } |
| 2417 if (*packet == '-') | 2552 if (*packet == '-') |
| 2418 { | 2553 { |
| 2419 trail_hyphen = 1; | 2554 trail_hyphen = 1; |
| 2420 trace_debug ("Also has actions\n"); | 2555 trace_debug ("Also has actions\n"); |
| 2421 } | 2556 } |
| 2422 | 2557 |
| 2423 trace_debug ("Defined %stracepoint %d at 0x%s, " | 2558 trace_debug ("Defined %stracepoint %d at 0x%s, " |
| 2424 » » "enabled %d step %ld pass %ld", | 2559 » » "enabled %d step %" PRIu64 " pass %" PRIu64, |
| 2425 tpoint->type == fast_tracepoint ? "fast " | 2560 tpoint->type == fast_tracepoint ? "fast " |
| 2426 » » : "", | 2561 » » : tpoint->type == static_tracepoint ? "static " : "", |
| 2427 tpoint->number, paddress (tpoint->address), tpoint->enabled, | 2562 tpoint->number, paddress (tpoint->address), tpoint->enabled, |
| 2428 tpoint->step_count, tpoint->pass_count); | 2563 tpoint->step_count, tpoint->pass_count); |
| 2429 } | 2564 } |
| 2430 else if (tpoint) | 2565 else if (tpoint) |
| 2431 add_tracepoint_action (tpoint, packet); | 2566 add_tracepoint_action (tpoint, packet); |
| 2432 else | 2567 else |
| 2433 { | 2568 { |
| 2434 trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found", | 2569 trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found", |
| 2435 (int) num, paddress (addr)); | 2570 (int) num, paddress (addr)); |
| 2436 write_enn (own_buf); | 2571 write_enn (own_buf); |
| 2437 return; | 2572 return; |
| 2438 } | 2573 } |
| 2439 | 2574 |
| 2440 /* Install tracepoint during tracing only once for each tracepoint location. | 2575 /* Install tracepoint during tracing only once for each tracepoint location. |
| 2441 For each tracepoint loc, GDB may send multiple QTDP packets, and we can | 2576 For each tracepoint loc, GDB may send multiple QTDP packets, and we can |
| 2442 determine the last QTDP packet for one tracepoint location by checking | 2577 determine the last QTDP packet for one tracepoint location by checking |
| 2443 trailing hyphen in QTDP packet. */ | 2578 trailing hyphen in QTDP packet. */ |
| 2444 if (tracing && !trail_hyphen) | 2579 if (tracing && !trail_hyphen) |
| 2445 { | 2580 { |
| 2581 struct tracepoint *tp = NULL; |
| 2582 |
| 2446 /* Pause all threads temporarily while we patch tracepoints. */ | 2583 /* Pause all threads temporarily while we patch tracepoints. */ |
| 2447 pause_all (0); | 2584 pause_all (0); |
| 2448 | 2585 |
| 2449 /* download_tracepoint will update global `tracepoints' | 2586 /* download_tracepoint will update global `tracepoints' |
| 2450 list, so it is unsafe to leave threads in jump pad. */ | 2587 list, so it is unsafe to leave threads in jump pad. */ |
| 2451 stabilize_threads (); | 2588 stabilize_threads (); |
| 2452 | 2589 |
| 2453 /* Freeze threads. */ | 2590 /* Freeze threads. */ |
| 2454 pause_all (1); | 2591 pause_all (1); |
| 2455 | 2592 |
| 2456 download_tracepoint (tpoint); | 2593 |
| 2457 install_tracepoint (tpoint, own_buf); | 2594 if (tpoint->type != trap_tracepoint) |
| 2595 » { |
| 2596 » /* Find another fast or static tracepoint at the same address. */ |
| 2597 » for (tp = tracepoints; tp; tp = tp->next) |
| 2598 » { |
| 2599 » if (tp->address == tpoint->address && tp->type == tpoint->type |
| 2600 » » && tp->number != tpoint->number) |
| 2601 » » break; |
| 2602 » } |
| 2603 |
| 2604 » /* TPOINT is installed at the same address as TP. */ |
| 2605 » if (tp) |
| 2606 » { |
| 2607 » if (tpoint->type == fast_tracepoint) |
| 2608 » » clone_fast_tracepoint (tpoint, tp); |
| 2609 » else if (tpoint->type == static_tracepoint) |
| 2610 » » tpoint->handle = (void *) -1; |
| 2611 » } |
| 2612 » } |
| 2613 |
| 2614 if (use_agent && tpoint->type == fast_tracepoint |
| 2615 » && agent_capability_check (AGENT_CAPA_FAST_TRACE)) |
| 2616 » { |
| 2617 » /* Download and install fast tracepoint by agent. */ |
| 2618 » if (tracepoint_send_agent (tpoint) == 0) |
| 2619 » write_ok (own_buf); |
| 2620 » else |
| 2621 » { |
| 2622 » write_enn (own_buf); |
| 2623 » remove_tracepoint (tpoint); |
| 2624 » } |
| 2625 » } |
| 2626 else |
| 2627 » { |
| 2628 » download_tracepoint (tpoint); |
| 2629 |
| 2630 » if (tpoint->type == trap_tracepoint || tp == NULL) |
| 2631 » { |
| 2632 » install_tracepoint (tpoint, own_buf); |
| 2633 » if (strcmp (own_buf, "OK") != 0) |
| 2634 » » remove_tracepoint (tpoint); |
| 2635 » } |
| 2636 » else |
| 2637 » write_ok (own_buf); |
| 2638 » } |
| 2458 | 2639 |
| 2459 unpause_all (1); | 2640 unpause_all (1); |
| 2460 return; | 2641 return; |
| 2461 } | 2642 } |
| 2462 | 2643 |
| 2463 write_ok (own_buf); | 2644 write_ok (own_buf); |
| 2464 } | 2645 } |
| 2465 | 2646 |
| 2466 static void | 2647 static void |
| 2467 cmd_qtdpsrc (char *own_buf) | 2648 cmd_qtdpsrc (char *own_buf) |
| (...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2834 | 3015 |
| 2835 /* Ask the IPA to probe the marker at ADDRESS. Returns -1 if running | 3016 /* Ask the IPA to probe the marker at ADDRESS. Returns -1 if running |
| 2836 the command fails, or 0 otherwise. If the command ran | 3017 the command fails, or 0 otherwise. If the command ran |
| 2837 successfully, but probing the marker failed, ERROUT will be filled | 3018 successfully, but probing the marker failed, ERROUT will be filled |
| 2838 with the error to reply to GDB, and -1 is also returned. This | 3019 with the error to reply to GDB, and -1 is also returned. This |
| 2839 allows directly passing IPA errors to GDB. */ | 3020 allows directly passing IPA errors to GDB. */ |
| 2840 | 3021 |
| 2841 static int | 3022 static int |
| 2842 probe_marker_at (CORE_ADDR address, char *errout) | 3023 probe_marker_at (CORE_ADDR address, char *errout) |
| 2843 { | 3024 { |
| 2844 char cmd[CMD_BUF_SIZE]; | 3025 char cmd[IPA_CMD_BUF_SIZE]; |
| 2845 int err; | 3026 int err; |
| 2846 | 3027 |
| 2847 sprintf (cmd, "probe_marker_at:%s", paddress (address)); | 3028 sprintf (cmd, "probe_marker_at:%s", paddress (address)); |
| 2848 err = run_inferior_command (cmd); | 3029 err = run_inferior_command (cmd, strlen (cmd) + 1); |
| 2849 | 3030 |
| 2850 if (err == 0) | 3031 if (err == 0) |
| 2851 { | 3032 { |
| 2852 if (*cmd == 'E') | 3033 if (*cmd == 'E') |
| 2853 { | 3034 { |
| 2854 strcpy (errout, cmd); | 3035 strcpy (errout, cmd); |
| 2855 return -1; | 3036 return -1; |
| 2856 } | 3037 } |
| 2857 } | 3038 } |
| 2858 | 3039 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2951 { | 3132 { |
| 2952 /* Tracepoints are installed as memory breakpoints. Just go | 3133 /* Tracepoints are installed as memory breakpoints. Just go |
| 2953 ahead and install the trap. The breakpoints module | 3134 ahead and install the trap. The breakpoints module |
| 2954 handles duplicated breakpoints, and the memory read | 3135 handles duplicated breakpoints, and the memory read |
| 2955 routine handles un-patching traps from memory reads. */ | 3136 routine handles un-patching traps from memory reads. */ |
| 2956 tpoint->handle = set_breakpoint_at (tpoint->address, | 3137 tpoint->handle = set_breakpoint_at (tpoint->address, |
| 2957 tracepoint_handler); | 3138 tracepoint_handler); |
| 2958 } | 3139 } |
| 2959 else if (tpoint->type == fast_tracepoint || tpoint->type == static_tracepoint) | 3140 else if (tpoint->type == fast_tracepoint || tpoint->type == static_tracepoint) |
| 2960 { | 3141 { |
| 2961 struct tracepoint *tp; | 3142 if (!agent_loaded_p ()) |
| 2962 | |
| 2963 if (!in_process_agent_loaded ()) | |
| 2964 { | 3143 { |
| 2965 trace_debug ("Requested a %s tracepoint, but fast " | 3144 trace_debug ("Requested a %s tracepoint, but fast " |
| 2966 "tracepoints aren't supported.", | 3145 "tracepoints aren't supported.", |
| 2967 tpoint->type == static_tracepoint ? "static" : "fast"); | 3146 tpoint->type == static_tracepoint ? "static" : "fast"); |
| 2968 write_e_ipa_not_loaded (own_buf); | 3147 write_e_ipa_not_loaded (own_buf); |
| 2969 return; | 3148 return; |
| 2970 } | 3149 } |
| 2971 if (tpoint->type == static_tracepoint && !in_process_agent_loaded_ust ()) | 3150 if (tpoint->type == static_tracepoint |
| 3151 » && !in_process_agent_supports_ust ()) |
| 2972 { | 3152 { |
| 2973 trace_debug ("Requested a static tracepoint, but static " | 3153 trace_debug ("Requested a static tracepoint, but static " |
| 2974 "tracepoints are not supported."); | 3154 "tracepoints are not supported."); |
| 2975 write_e_ust_not_loaded (own_buf); | 3155 write_e_ust_not_loaded (own_buf); |
| 2976 return; | 3156 return; |
| 2977 } | 3157 } |
| 2978 | 3158 |
| 2979 /* Find another fast or static tracepoint at the same address. */ | |
| 2980 for (tp = tracepoints; tp; tp = tp->next) | |
| 2981 { | |
| 2982 if (tp->address == tpoint->address && tp->type == tpoint->type | |
| 2983 && tp->number != tpoint->number) | |
| 2984 break; | |
| 2985 } | |
| 2986 | |
| 2987 if (tpoint->type == fast_tracepoint) | 3159 if (tpoint->type == fast_tracepoint) |
| 2988 » { | 3160 » install_fast_tracepoint (tpoint, own_buf); |
| 2989 » if (tp) /* TPOINT is installed at the same address as TP. */ | |
| 2990 » clone_fast_tracepoint (tpoint, tp); | |
| 2991 » else | |
| 2992 » install_fast_tracepoint (tpoint, own_buf); | |
| 2993 » } | |
| 2994 else | 3161 else |
| 2995 { | 3162 { |
| 2996 » if (tp) | 3163 » if (probe_marker_at (tpoint->address, own_buf) == 0) |
| 2997 tpoint->handle = (void *) -1; | 3164 tpoint->handle = (void *) -1; |
| 2998 else | |
| 2999 { | |
| 3000 if (probe_marker_at (tpoint->address, own_buf) == 0) | |
| 3001 tpoint->handle = (void *) -1; | |
| 3002 } | |
| 3003 } | 3165 } |
| 3004 | 3166 |
| 3005 } | 3167 } |
| 3006 else | 3168 else |
| 3007 internal_error (__FILE__, __LINE__, "Unknown tracepoint type"); | 3169 internal_error (__FILE__, __LINE__, "Unknown tracepoint type"); |
| 3008 | 3170 |
| 3009 if (tpoint->handle == NULL) | 3171 if (tpoint->handle == NULL) |
| 3010 { | 3172 { |
| 3011 if (*own_buf == '\0') | 3173 if (*own_buf == '\0') |
| 3012 write_enn (own_buf); | 3174 write_enn (own_buf); |
| 3013 } | 3175 } |
| 3014 else | 3176 else |
| 3015 write_ok (own_buf); | 3177 write_ok (own_buf); |
| 3016 } | 3178 } |
| 3017 | 3179 |
| 3180 static void download_tracepoint_1 (struct tracepoint *tpoint); |
| 3181 |
| 3018 static void | 3182 static void |
| 3019 cmd_qtstart (char *packet) | 3183 cmd_qtstart (char *packet) |
| 3020 { | 3184 { |
| 3021 struct tracepoint *tpoint, *prev_ftpoint, *prev_stpoint; | 3185 struct tracepoint *tpoint, *prev_ftpoint, *prev_stpoint; |
| 3186 CORE_ADDR tpptr = 0, prev_tpptr = 0; |
| 3022 | 3187 |
| 3023 trace_debug ("Starting the trace"); | 3188 trace_debug ("Starting the trace"); |
| 3024 | 3189 |
| 3025 /* Pause all threads temporarily while we patch tracepoints. */ | 3190 /* Pause all threads temporarily while we patch tracepoints. */ |
| 3026 pause_all (0); | 3191 pause_all (0); |
| 3027 | 3192 |
| 3028 /* Get threads out of jump pads. Safe to do here, since this is a | 3193 /* Get threads out of jump pads. Safe to do here, since this is a |
| 3029 top level command. And, required to do here, since we're | 3194 top level command. And, required to do here, since we're |
| 3030 deleting/rewriting jump pads. */ | 3195 deleting/rewriting jump pads. */ |
| 3031 | 3196 |
| 3032 stabilize_threads (); | 3197 stabilize_threads (); |
| 3033 | 3198 |
| 3034 /* Freeze threads. */ | 3199 /* Freeze threads. */ |
| 3035 pause_all (1); | 3200 pause_all (1); |
| 3036 | 3201 |
| 3037 /* Sync the fast tracepoints list in the inferior ftlib. */ | 3202 /* Sync the fast tracepoints list in the inferior ftlib. */ |
| 3038 if (in_process_agent_loaded ()) | 3203 if (agent_loaded_p ()) |
| 3039 { | 3204 download_trace_state_variables (); |
| 3040 download_tracepoints (); | |
| 3041 download_trace_state_variables (); | |
| 3042 } | |
| 3043 | 3205 |
| 3044 /* No previous fast tpoint yet. */ | 3206 /* No previous fast tpoint yet. */ |
| 3045 prev_ftpoint = NULL; | 3207 prev_ftpoint = NULL; |
| 3046 | 3208 |
| 3047 /* No previous static tpoint yet. */ | 3209 /* No previous static tpoint yet. */ |
| 3048 prev_stpoint = NULL; | 3210 prev_stpoint = NULL; |
| 3049 | 3211 |
| 3050 *packet = '\0'; | 3212 *packet = '\0'; |
| 3051 | 3213 |
| 3052 /* Install tracepoints. */ | 3214 /* Start out empty. */ |
| 3215 if (agent_loaded_p ()) |
| 3216 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, 0); |
| 3217 |
| 3218 /* Download and install tracepoints. */ |
| 3053 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) | 3219 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) |
| 3054 { | 3220 { |
| 3055 /* Ensure all the hit counts start at zero. */ | 3221 /* Ensure all the hit counts start at zero. */ |
| 3056 tpoint->hit_count = 0; | 3222 tpoint->hit_count = 0; |
| 3057 tpoint->traceframe_usage = 0; | 3223 tpoint->traceframe_usage = 0; |
| 3058 | 3224 |
| 3059 if (tpoint->type == trap_tracepoint) | 3225 if (tpoint->type == trap_tracepoint) |
| 3060 { | 3226 { |
| 3061 /* Tracepoints are installed as memory breakpoints. Just go | 3227 /* Tracepoints are installed as memory breakpoints. Just go |
| 3062 ahead and install the trap. The breakpoints module | 3228 ahead and install the trap. The breakpoints module |
| 3063 handles duplicated breakpoints, and the memory read | 3229 handles duplicated breakpoints, and the memory read |
| 3064 routine handles un-patching traps from memory reads. */ | 3230 routine handles un-patching traps from memory reads. */ |
| 3065 tpoint->handle = set_breakpoint_at (tpoint->address, | 3231 tpoint->handle = set_breakpoint_at (tpoint->address, |
| 3066 tracepoint_handler); | 3232 tracepoint_handler); |
| 3067 } | 3233 } |
| 3068 else if (tpoint->type == fast_tracepoint) | 3234 else if (tpoint->type == fast_tracepoint |
| 3235 » || tpoint->type == static_tracepoint) |
| 3069 { | 3236 { |
| 3070 if (maybe_write_ipa_not_loaded (packet)) | 3237 if (maybe_write_ipa_not_loaded (packet)) |
| 3071 { | 3238 { |
| 3072 » trace_debug ("Requested a fast tracepoint, but fast " | 3239 » trace_debug ("Requested a %s tracepoint, but fast " |
| 3073 » » » "tracepoints aren't supported."); | 3240 » » » "tracepoints aren't supported.", |
| 3241 » » » tpoint->type == static_tracepoint |
| 3242 » » » ? "static" : "fast"); |
| 3074 break; | 3243 break; |
| 3075 } | 3244 } |
| 3076 | 3245 |
| 3077 » if (prev_ftpoint != NULL && prev_ftpoint->address == tpoint->address) | 3246 » if (tpoint->type == fast_tracepoint) |
| 3078 » clone_fast_tracepoint (tpoint, prev_ftpoint); | |
| 3079 » else | |
| 3080 { | 3247 { |
| 3081 » if (install_fast_tracepoint (tpoint, packet) == 0) | 3248 » int use_agent_p |
| 3082 » » prev_ftpoint = tpoint; | 3249 » » = use_agent && agent_capability_check (AGENT_CAPA_FAST_TRACE); |
| 3083 » } | |
| 3084 » } | |
| 3085 else if (tpoint->type == static_tracepoint) | |
| 3086 » { | |
| 3087 » if (maybe_write_ipa_ust_not_loaded (packet)) | |
| 3088 » { | |
| 3089 » trace_debug ("Requested a static tracepoint, but static " | |
| 3090 » » » "tracepoints are not supported."); | |
| 3091 » break; | |
| 3092 » } | |
| 3093 | 3250 |
| 3094 » /* Can only probe a given marker once. */ | 3251 » if (prev_ftpoint != NULL |
| 3095 » if (prev_stpoint != NULL && prev_stpoint->address == tpoint->address) | 3252 » » && prev_ftpoint->address == tpoint->address) |
| 3096 » { | 3253 » » { |
| 3097 » tpoint->handle = (void *) -1; | 3254 » » if (use_agent_p) |
| 3255 » » tracepoint_send_agent (tpoint); |
| 3256 » » else |
| 3257 » » download_tracepoint_1 (tpoint); |
| 3258 |
| 3259 » » clone_fast_tracepoint (tpoint, prev_ftpoint); |
| 3260 » » } |
| 3261 » else |
| 3262 » » { |
| 3263 » » /* Tracepoint is installed successfully? */ |
| 3264 » » int installed = 0; |
| 3265 |
| 3266 » » /* Download and install fast tracepoint by agent. */ |
| 3267 » » if (use_agent_p) |
| 3268 » » installed = !tracepoint_send_agent (tpoint); |
| 3269 » » else |
| 3270 » » { |
| 3271 » » download_tracepoint_1 (tpoint); |
| 3272 » » installed = !install_fast_tracepoint (tpoint, packet); |
| 3273 » » } |
| 3274 |
| 3275 » » if (installed) |
| 3276 » » prev_ftpoint = tpoint; |
| 3277 » » } |
| 3098 } | 3278 } |
| 3099 else | 3279 else |
| 3100 { | 3280 { |
| 3101 » if (probe_marker_at (tpoint->address, packet) == 0) | 3281 » if (!in_process_agent_supports_ust ()) |
| 3102 { | 3282 { |
| 3103 » » tpoint->handle = (void *) -1; | 3283 » » trace_debug ("Requested a static tracepoint, but static " |
| 3284 » » » "tracepoints are not supported."); |
| 3285 » » break; |
| 3286 » » } |
| 3104 | 3287 |
| 3105 » » /* So that we can handle multiple static tracepoints | 3288 » download_tracepoint_1 (tpoint); |
| 3106 » » at the same address easily. */ | 3289 » /* Can only probe a given marker once. */ |
| 3107 » » prev_stpoint = tpoint; | 3290 » if (prev_stpoint != NULL |
| 3291 » » && prev_stpoint->address == tpoint->address) |
| 3292 » » tpoint->handle = (void *) -1; |
| 3293 » else |
| 3294 » » { |
| 3295 » » if (probe_marker_at (tpoint->address, packet) == 0) |
| 3296 » » { |
| 3297 » » tpoint->handle = (void *) -1; |
| 3298 |
| 3299 » » /* So that we can handle multiple static tracepoints |
| 3300 » » » at the same address easily. */ |
| 3301 » » prev_stpoint = tpoint; |
| 3302 » » } |
| 3108 } | 3303 } |
| 3109 } | 3304 } |
| 3305 |
| 3306 prev_tpptr = tpptr; |
| 3307 tpptr = tpoint->obj_addr_on_target; |
| 3308 |
| 3309 if (tpoint == tracepoints) |
| 3310 /* First object in list, set the head pointer in the |
| 3311 inferior. */ |
| 3312 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, tpptr); |
| 3313 else |
| 3314 write_inferior_data_ptr (prev_tpptr + offsetof (struct tracepoint, |
| 3315 next), |
| 3316 tpptr); |
| 3110 } | 3317 } |
| 3111 | 3318 |
| 3112 /* Any failure in the inner loop is sufficient cause to give | 3319 /* Any failure in the inner loop is sufficient cause to give |
| 3113 up. */ | 3320 up. */ |
| 3114 if (tpoint->handle == NULL) | 3321 if (tpoint->handle == NULL) |
| 3115 break; | 3322 break; |
| 3116 } | 3323 } |
| 3117 | 3324 |
| 3118 /* Any error in tracepoint insertion is unacceptable; better to | 3325 /* Any error in tracepoint insertion is unacceptable; better to |
| 3119 address the problem now, than end up with a useless or misleading | 3326 address the problem now, than end up with a useless or misleading |
| 3120 trace run. */ | 3327 trace run. */ |
| 3121 if (tpoint != NULL) | 3328 if (tpoint != NULL) |
| 3122 { | 3329 { |
| 3123 clear_installed_tracepoints (); | 3330 clear_installed_tracepoints (); |
| 3124 if (*packet == '\0') | 3331 if (*packet == '\0') |
| 3125 write_enn (packet); | 3332 write_enn (packet); |
| 3126 unpause_all (1); | 3333 unpause_all (1); |
| 3127 return; | 3334 return; |
| 3128 } | 3335 } |
| 3129 | 3336 |
| 3130 stopping_tracepoint = NULL; | 3337 stopping_tracepoint = NULL; |
| 3131 trace_buffer_is_full = 0; | 3338 trace_buffer_is_full = 0; |
| 3132 expr_eval_result = expr_eval_no_error; | 3339 expr_eval_result = expr_eval_no_error; |
| 3133 error_tracepoint = NULL; | 3340 error_tracepoint = NULL; |
| 3134 tracing_start_time = get_timestamp (); | 3341 tracing_start_time = get_timestamp (); |
| 3135 | 3342 |
| 3136 /* Tracing is now active, hits will now start being logged. */ | 3343 /* Tracing is now active, hits will now start being logged. */ |
| 3137 tracing = 1; | 3344 tracing = 1; |
| 3138 | 3345 |
| 3139 if (in_process_agent_loaded ()) | 3346 if (agent_loaded_p ()) |
| 3140 { | 3347 { |
| 3141 if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 1)) | 3348 if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 1)) |
| 3142 fatal ("Error setting tracing variable in lib"); | 3349 fatal ("Error setting tracing variable in lib"); |
| 3143 | 3350 |
| 3144 if (write_inferior_data_pointer (ipa_sym_addrs.addr_stopping_tracepoint, | 3351 if (write_inferior_data_pointer (ipa_sym_addrs.addr_stopping_tracepoint, |
| 3145 0)) | 3352 0)) |
| 3146 fatal ("Error clearing stopping_tracepoint variable in lib"); | 3353 fatal ("Error clearing stopping_tracepoint variable in lib"); |
| 3147 | 3354 |
| 3148 if (write_inferior_integer (ipa_sym_addrs.addr_trace_buffer_is_full, 0)) | 3355 if (write_inferior_integer (ipa_sym_addrs.addr_trace_buffer_is_full, 0)) |
| 3149 fatal ("Error clearing trace_buffer_is_full variable in lib"); | 3356 fatal ("Error clearing trace_buffer_is_full variable in lib"); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3188 We can't now, since we may be getting here due to the inferior | 3395 We can't now, since we may be getting here due to the inferior |
| 3189 agent calling us. */ | 3396 agent calling us. */ |
| 3190 pause_all (1); | 3397 pause_all (1); |
| 3191 /* Since we're removing breakpoints, cancel breakpoint hits, | 3398 /* Since we're removing breakpoints, cancel breakpoint hits, |
| 3192 possibly related to the breakpoints we're about to delete. */ | 3399 possibly related to the breakpoints we're about to delete. */ |
| 3193 cancel_breakpoints (); | 3400 cancel_breakpoints (); |
| 3194 | 3401 |
| 3195 /* Stop logging. Tracepoints can still be hit, but they will not be | 3402 /* Stop logging. Tracepoints can still be hit, but they will not be |
| 3196 recorded. */ | 3403 recorded. */ |
| 3197 tracing = 0; | 3404 tracing = 0; |
| 3198 if (in_process_agent_loaded ()) | 3405 if (agent_loaded_p ()) |
| 3199 { | 3406 { |
| 3200 if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 0)) | 3407 if (write_inferior_integer (ipa_sym_addrs.addr_tracing, 0)) |
| 3201 fatal ("Error clearing tracing variable in lib"); | 3408 fatal ("Error clearing tracing variable in lib"); |
| 3202 } | 3409 } |
| 3203 | 3410 |
| 3204 tracing_stop_time = get_timestamp (); | 3411 tracing_stop_time = get_timestamp (); |
| 3205 tracing_stop_reason = "t???"; | 3412 tracing_stop_reason = "t???"; |
| 3206 tracing_stop_tpnum = 0; | 3413 tracing_stop_tpnum = 0; |
| 3207 if (stopping_tracepoint) | 3414 if (stopping_tracepoint) |
| 3208 { | 3415 { |
| 3209 trace_debug ("Stopping the trace because " | 3416 trace_debug ("Stopping the trace because " |
| 3210 » » "tracepoint %d was hit %ld times", | 3417 » » "tracepoint %d was hit %" PRIu64 " times", |
| 3211 stopping_tracepoint->number, | 3418 stopping_tracepoint->number, |
| 3212 stopping_tracepoint->pass_count); | 3419 stopping_tracepoint->pass_count); |
| 3213 tracing_stop_reason = "tpasscount"; | 3420 tracing_stop_reason = "tpasscount"; |
| 3214 tracing_stop_tpnum = stopping_tracepoint->number; | 3421 tracing_stop_tpnum = stopping_tracepoint->number; |
| 3215 } | 3422 } |
| 3216 else if (trace_buffer_is_full) | 3423 else if (trace_buffer_is_full) |
| 3217 { | 3424 { |
| 3218 trace_debug ("Stopping the trace because the trace buffer is full"); | 3425 trace_debug ("Stopping the trace because the trace buffer is full"); |
| 3219 tracing_stop_reason = "tfull"; | 3426 tracing_stop_reason = "tfull"; |
| 3220 } | 3427 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 3236 trace_debug ("Stopping the trace because of a tstop command"); | 3443 trace_debug ("Stopping the trace because of a tstop command"); |
| 3237 tracing_stop_reason = "tstop"; | 3444 tracing_stop_reason = "tstop"; |
| 3238 } | 3445 } |
| 3239 | 3446 |
| 3240 stopping_tracepoint = NULL; | 3447 stopping_tracepoint = NULL; |
| 3241 error_tracepoint = NULL; | 3448 error_tracepoint = NULL; |
| 3242 | 3449 |
| 3243 /* Clear out the tracepoints. */ | 3450 /* Clear out the tracepoints. */ |
| 3244 clear_installed_tracepoints (); | 3451 clear_installed_tracepoints (); |
| 3245 | 3452 |
| 3246 if (in_process_agent_loaded ()) | 3453 if (agent_loaded_p ()) |
| 3247 { | 3454 { |
| 3248 /* Pull in fast tracepoint trace frames from the inferior lib | 3455 /* Pull in fast tracepoint trace frames from the inferior lib |
| 3249 buffer into our buffer, even if our buffer is already full, | 3456 buffer into our buffer, even if our buffer is already full, |
| 3250 because we want to present the full number of created frames | 3457 because we want to present the full number of created frames |
| 3251 in addition to what fit in the trace buffer. */ | 3458 in addition to what fit in the trace buffer. */ |
| 3252 upload_fast_traceframes (); | 3459 upload_fast_traceframes (); |
| 3253 } | 3460 } |
| 3254 | 3461 |
| 3255 if (stop_tracing_bkpt != NULL) | 3462 if (stop_tracing_bkpt != NULL) |
| 3256 { | 3463 { |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 hexify (buf2, str, slen); | 3606 hexify (buf2, str, slen); |
| 3400 | 3607 |
| 3401 str = (tracing_stop_note ? tracing_stop_note : ""); | 3608 str = (tracing_stop_note ? tracing_stop_note : ""); |
| 3402 slen = strlen (str); | 3609 slen = strlen (str); |
| 3403 buf3 = (char *) alloca (slen * 2 + 1); | 3610 buf3 = (char *) alloca (slen * 2 + 1); |
| 3404 hexify (buf3, str, slen); | 3611 hexify (buf3, str, slen); |
| 3405 | 3612 |
| 3406 trace_debug ("Returning trace status as %d, stop reason %s", | 3613 trace_debug ("Returning trace status as %d, stop reason %s", |
| 3407 tracing, tracing_stop_reason); | 3614 tracing, tracing_stop_reason); |
| 3408 | 3615 |
| 3409 if (in_process_agent_loaded ()) | 3616 if (agent_loaded_p ()) |
| 3410 { | 3617 { |
| 3411 pause_all (1); | 3618 pause_all (1); |
| 3412 | 3619 |
| 3413 upload_fast_traceframes (); | 3620 upload_fast_traceframes (); |
| 3414 | 3621 |
| 3415 unpause_all (1); | 3622 unpause_all (1); |
| 3416 } | 3623 } |
| 3417 | 3624 |
| 3418 stop_reason_rsp = (char *) tracing_stop_reason; | 3625 stop_reason_rsp = (char *) tracing_stop_reason; |
| 3419 | 3626 |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3478 tpoint = find_tracepoint (num, addr); | 3685 tpoint = find_tracepoint (num, addr); |
| 3479 | 3686 |
| 3480 if (!tpoint) | 3687 if (!tpoint) |
| 3481 { | 3688 { |
| 3482 trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found", | 3689 trace_debug ("Tracepoint error: tracepoint %d at 0x%s not found", |
| 3483 (int) num, paddress (addr)); | 3690 (int) num, paddress (addr)); |
| 3484 write_enn (own_buf); | 3691 write_enn (own_buf); |
| 3485 return; | 3692 return; |
| 3486 } | 3693 } |
| 3487 | 3694 |
| 3488 sprintf (own_buf, "V%lx:%lx", tpoint->hit_count, tpoint->traceframe_usage); | 3695 sprintf (own_buf, "V%" PRIu64 ":%" PRIu64 "", tpoint->hit_count, |
| 3696 » tpoint->traceframe_usage); |
| 3489 } | 3697 } |
| 3490 | 3698 |
| 3491 /* State variables to help return all the tracepoint bits. */ | 3699 /* State variables to help return all the tracepoint bits. */ |
| 3492 static struct tracepoint *cur_tpoint; | 3700 static struct tracepoint *cur_tpoint; |
| 3493 static int cur_action; | 3701 static int cur_action; |
| 3494 static int cur_step_action; | 3702 static int cur_step_action; |
| 3495 static struct source_string *cur_source_string; | 3703 static struct source_string *cur_source_string; |
| 3496 static struct trace_state_variable *cur_tsv; | 3704 static struct trace_state_variable *cur_tsv; |
| 3497 | 3705 |
| 3498 /* Compose a response that is an imitation of the syntax by which the | 3706 /* Compose a response that is an imitation of the syntax by which the |
| 3499 tracepoint was originally downloaded. */ | 3707 tracepoint was originally downloaded. */ |
| 3500 | 3708 |
| 3501 static void | 3709 static void |
| 3502 response_tracepoint (char *packet, struct tracepoint *tpoint) | 3710 response_tracepoint (char *packet, struct tracepoint *tpoint) |
| 3503 { | 3711 { |
| 3504 char *buf; | 3712 char *buf; |
| 3505 | 3713 |
| 3506 sprintf (packet, "T%x:%s:%c:%lx:%lx", tpoint->number, | 3714 sprintf (packet, "T%x:%s:%c:%" PRIx64 ":%" PRIx64, tpoint->number, |
| 3507 paddress (tpoint->address), | 3715 paddress (tpoint->address), |
| 3508 (tpoint->enabled ? 'E' : 'D'), tpoint->step_count, | 3716 (tpoint->enabled ? 'E' : 'D'), tpoint->step_count, |
| 3509 tpoint->pass_count); | 3717 tpoint->pass_count); |
| 3510 if (tpoint->type == fast_tracepoint) | 3718 if (tpoint->type == fast_tracepoint) |
| 3511 sprintf (packet + strlen (packet), ":F%x", tpoint->orig_size); | 3719 sprintf (packet + strlen (packet), ":F%x", tpoint->orig_size); |
| 3512 else if (tpoint->type == static_tracepoint) | 3720 else if (tpoint->type == static_tracepoint) |
| 3513 sprintf (packet + strlen (packet), ":S"); | 3721 sprintf (packet + strlen (packet), ":S"); |
| 3514 | 3722 |
| 3515 if (tpoint->cond) | 3723 if (tpoint->cond) |
| 3516 { | 3724 { |
| 3517 buf = unparse_agent_expr (tpoint->cond); | 3725 buf = gdb_unparse_agent_expr (tpoint->cond); |
| 3518 sprintf (packet + strlen (packet), ":X%x,%s", | 3726 sprintf (packet + strlen (packet), ":X%x,%s", |
| 3519 tpoint->cond->length, buf); | 3727 tpoint->cond->length, buf); |
| 3520 free (buf); | 3728 free (buf); |
| 3521 } | 3729 } |
| 3522 } | 3730 } |
| 3523 | 3731 |
| 3524 /* Compose a response that is an imitation of the syntax by which the | 3732 /* Compose a response that is an imitation of the syntax by which the |
| 3525 tracepoint action was originally downloaded (with the difference | 3733 tracepoint action was originally downloaded (with the difference |
| 3526 that due to the way we store the actions, this will output a packet | 3734 that due to the way we store the actions, this will output a packet |
| 3527 per action, while GDB could have combined more than one action | 3735 per action, while GDB could have combined more than one action |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3686 } | 3894 } |
| 3687 | 3895 |
| 3688 /* Return the first static tracepoint marker, and initialize the state | 3896 /* Return the first static tracepoint marker, and initialize the state |
| 3689 machine that will iterate through all the static tracepoints | 3897 machine that will iterate through all the static tracepoints |
| 3690 markers. */ | 3898 markers. */ |
| 3691 | 3899 |
| 3692 static void | 3900 static void |
| 3693 cmd_qtfstm (char *packet) | 3901 cmd_qtfstm (char *packet) |
| 3694 { | 3902 { |
| 3695 if (!maybe_write_ipa_ust_not_loaded (packet)) | 3903 if (!maybe_write_ipa_ust_not_loaded (packet)) |
| 3696 run_inferior_command (packet); | 3904 run_inferior_command (packet, strlen (packet) + 1); |
| 3697 } | 3905 } |
| 3698 | 3906 |
| 3699 /* Return additional static tracepoints markers. */ | 3907 /* Return additional static tracepoints markers. */ |
| 3700 | 3908 |
| 3701 static void | 3909 static void |
| 3702 cmd_qtsstm (char *packet) | 3910 cmd_qtsstm (char *packet) |
| 3703 { | 3911 { |
| 3704 if (!maybe_write_ipa_ust_not_loaded (packet)) | 3912 if (!maybe_write_ipa_ust_not_loaded (packet)) |
| 3705 run_inferior_command (packet); | 3913 run_inferior_command (packet, strlen (packet) + 1); |
| 3706 } | 3914 } |
| 3707 | 3915 |
| 3708 /* Return the definition of the static tracepoint at a given address. | 3916 /* Return the definition of the static tracepoint at a given address. |
| 3709 Result packet is the same as qTsST's. */ | 3917 Result packet is the same as qTsST's. */ |
| 3710 | 3918 |
| 3711 static void | 3919 static void |
| 3712 cmd_qtstmat (char *packet) | 3920 cmd_qtstmat (char *packet) |
| 3713 { | 3921 { |
| 3714 if (!maybe_write_ipa_ust_not_loaded (packet)) | 3922 if (!maybe_write_ipa_ust_not_loaded (packet)) |
| 3715 run_inferior_command (packet); | 3923 run_inferior_command (packet, strlen (packet) + 1); |
| 3716 } | 3924 } |
| 3717 | 3925 |
| 3718 /* Return the minimum instruction size needed for fast tracepoints as a | 3926 /* Return the minimum instruction size needed for fast tracepoints as a |
| 3719 hexadecimal number. */ | 3927 hexadecimal number. */ |
| 3720 | 3928 |
| 3721 static void | 3929 static void |
| 3722 cmd_qtminftpilen (char *packet) | 3930 cmd_qtminftpilen (char *packet) |
| 3723 { | 3931 { |
| 3932 if (current_inferior == NULL) |
| 3933 { |
| 3934 /* Indicate that the minimum length is currently unknown. */ |
| 3935 strcpy (packet, "0"); |
| 3936 return; |
| 3937 } |
| 3938 |
| 3724 sprintf (packet, "%x", target_get_min_fast_tracepoint_insn_len ()); | 3939 sprintf (packet, "%x", target_get_min_fast_tracepoint_insn_len ()); |
| 3725 } | 3940 } |
| 3726 | 3941 |
| 3727 /* Respond to qTBuffer packet with a block of raw data from the trace | 3942 /* Respond to qTBuffer packet with a block of raw data from the trace |
| 3728 buffer. GDB may ask for a lot, but we are allowed to reply with | 3943 buffer. GDB may ask for a lot, but we are allowed to reply with |
| 3729 only as much as will fit within packet limits or whatever. */ | 3944 only as much as will fit within packet limits or whatever. */ |
| 3730 | 3945 |
| 3731 static void | 3946 static void |
| 3732 cmd_qtbuffer (char *own_buf) | 3947 cmd_qtbuffer (char *own_buf) |
| 3733 { | 3948 { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3772 | 3987 |
| 3773 /* Trim to available packet size. */ | 3988 /* Trim to available packet size. */ |
| 3774 if (num >= (PBUFSIZ - 16) / 2 ) | 3989 if (num >= (PBUFSIZ - 16) / 2 ) |
| 3775 num = (PBUFSIZ - 16) / 2; | 3990 num = (PBUFSIZ - 16) / 2; |
| 3776 | 3991 |
| 3777 convert_int_to_ascii (tbp, own_buf, num); | 3992 convert_int_to_ascii (tbp, own_buf, num); |
| 3778 own_buf[num] = '\0'; | 3993 own_buf[num] = '\0'; |
| 3779 } | 3994 } |
| 3780 | 3995 |
| 3781 static void | 3996 static void |
| 3782 cmd_bigqtbuffer (char *own_buf) | 3997 cmd_bigqtbuffer_circular (char *own_buf) |
| 3783 { | 3998 { |
| 3784 ULONGEST val; | 3999 ULONGEST val; |
| 3785 char *packet = own_buf; | 4000 char *packet = own_buf; |
| 3786 | 4001 |
| 3787 packet += strlen ("QTBuffer:"); | 4002 packet += strlen ("QTBuffer:circular:"); |
| 3788 | 4003 |
| 3789 if (strncmp ("circular:", packet, strlen ("circular:")) == 0) | 4004 unpack_varlen_hex (packet, &val); |
| 3790 { | 4005 circular_trace_buffer = val; |
| 3791 packet += strlen ("circular:"); | 4006 trace_debug ("Trace buffer is now %s", |
| 3792 unpack_varlen_hex (packet, &val); | 4007 » circular_trace_buffer ? "circular" : "linear"); |
| 3793 circular_trace_buffer = val; | 4008 write_ok (own_buf); |
| 3794 trace_debug ("Trace buffer is now %s", | |
| 3795 » » circular_trace_buffer ? "circular" : "linear"); | |
| 3796 write_ok (own_buf); | |
| 3797 } | |
| 3798 else | |
| 3799 write_enn (own_buf); | |
| 3800 } | 4009 } |
| 3801 | 4010 |
| 3802 static void | 4011 static void |
| 3803 cmd_qtnotes (char *own_buf) | 4012 cmd_qtnotes (char *own_buf) |
| 3804 { | 4013 { |
| 3805 size_t nbytes; | 4014 size_t nbytes; |
| 3806 char *saved, *user, *notes, *stopnote; | 4015 char *saved, *user, *notes, *stopnote; |
| 3807 char *packet = own_buf; | 4016 char *packet = own_buf; |
| 3808 | 4017 |
| 3809 packet += strlen ("QTNotes:"); | 4018 packet += strlen ("QTNotes:"); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3908 strlen ("QTDisconnected:")) == 0) | 4117 strlen ("QTDisconnected:")) == 0) |
| 3909 { | 4118 { |
| 3910 cmd_qtdisconnected (packet); | 4119 cmd_qtdisconnected (packet); |
| 3911 return 1; | 4120 return 1; |
| 3912 } | 4121 } |
| 3913 else if (strncmp ("QTFrame:", packet, strlen ("QTFrame:")) == 0) | 4122 else if (strncmp ("QTFrame:", packet, strlen ("QTFrame:")) == 0) |
| 3914 { | 4123 { |
| 3915 cmd_qtframe (packet); | 4124 cmd_qtframe (packet); |
| 3916 return 1; | 4125 return 1; |
| 3917 } | 4126 } |
| 3918 else if (strncmp ("QTBuffer:", packet, strlen ("QTBuffer:")) == 0) | 4127 else if (strncmp ("QTBuffer:circular:", packet, strlen ("QTBuffer:circular:"))
== 0) |
| 3919 { | 4128 { |
| 3920 cmd_bigqtbuffer (packet); | 4129 cmd_bigqtbuffer_circular (packet); |
| 3921 return 1; | 4130 return 1; |
| 3922 } | 4131 } |
| 3923 else if (strncmp ("QTNotes:", packet, strlen ("QTNotes:")) == 0) | 4132 else if (strncmp ("QTNotes:", packet, strlen ("QTNotes:")) == 0) |
| 3924 { | 4133 { |
| 3925 cmd_qtnotes (packet); | 4134 cmd_qtnotes (packet); |
| 3926 return 1; | 4135 return 1; |
| 3927 } | 4136 } |
| 3928 | 4137 |
| 3929 return 0; | 4138 return 0; |
| 3930 } | 4139 } |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4066 int | 4275 int |
| 4067 tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc) | 4276 tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc) |
| 4068 { | 4277 { |
| 4069 struct tracepoint *tpoint; | 4278 struct tracepoint *tpoint; |
| 4070 struct wstep_state *wstep; | 4279 struct wstep_state *wstep; |
| 4071 struct wstep_state **wstep_link; | 4280 struct wstep_state **wstep_link; |
| 4072 struct trap_tracepoint_ctx ctx; | 4281 struct trap_tracepoint_ctx ctx; |
| 4073 | 4282 |
| 4074 /* Pull in fast tracepoint trace frames from the inferior lib buffer into | 4283 /* Pull in fast tracepoint trace frames from the inferior lib buffer into |
| 4075 our buffer. */ | 4284 our buffer. */ |
| 4076 if (in_process_agent_loaded ()) | 4285 if (agent_loaded_p ()) |
| 4077 upload_fast_traceframes (); | 4286 upload_fast_traceframes (); |
| 4078 | 4287 |
| 4079 /* Check if we were indeed collecting data for one of more | 4288 /* Check if we were indeed collecting data for one of more |
| 4080 tracepoints with a 'while-stepping' count. */ | 4289 tracepoints with a 'while-stepping' count. */ |
| 4081 if (tinfo->while_stepping == NULL) | 4290 if (tinfo->while_stepping == NULL) |
| 4082 return 0; | 4291 return 0; |
| 4083 | 4292 |
| 4084 if (!tracing) | 4293 if (!tracing) |
| 4085 { | 4294 { |
| 4086 /* We're not even tracing anymore. Stop this thread from | 4295 /* We're not even tracing anymore. Stop this thread from |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4167 /* Handle any internal tracing control breakpoint hits. That means, | 4376 /* Handle any internal tracing control breakpoint hits. That means, |
| 4168 pull traceframes from the IPA to our buffer, and syncing both | 4377 pull traceframes from the IPA to our buffer, and syncing both |
| 4169 tracing agents when the IPA's tracing stops for some reason. */ | 4378 tracing agents when the IPA's tracing stops for some reason. */ |
| 4170 | 4379 |
| 4171 int | 4380 int |
| 4172 handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc) | 4381 handle_tracepoint_bkpts (struct thread_info *tinfo, CORE_ADDR stop_pc) |
| 4173 { | 4382 { |
| 4174 /* Pull in fast tracepoint trace frames from the inferior in-process | 4383 /* Pull in fast tracepoint trace frames from the inferior in-process |
| 4175 agent's buffer into our buffer. */ | 4384 agent's buffer into our buffer. */ |
| 4176 | 4385 |
| 4177 if (!in_process_agent_loaded ()) | 4386 if (!agent_loaded_p ()) |
| 4178 return 0; | 4387 return 0; |
| 4179 | 4388 |
| 4180 upload_fast_traceframes (); | 4389 upload_fast_traceframes (); |
| 4181 | 4390 |
| 4182 /* Check if the in-process agent had decided we should stop | 4391 /* Check if the in-process agent had decided we should stop |
| 4183 tracing. */ | 4392 tracing. */ |
| 4184 if (stop_pc == ipa_sym_addrs.addr_stop_tracing) | 4393 if (stop_pc == ipa_sym_addrs.addr_stop_tracing) |
| 4185 { | 4394 { |
| 4186 int ipa_trace_buffer_is_full; | 4395 int ipa_trace_buffer_is_full; |
| 4187 CORE_ADDR ipa_stopping_tracepoint; | 4396 CORE_ADDR ipa_stopping_tracepoint; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4261 if (!tracing) | 4470 if (!tracing) |
| 4262 return 0; | 4471 return 0; |
| 4263 | 4472 |
| 4264 ctx.base.type = trap_tracepoint; | 4473 ctx.base.type = trap_tracepoint; |
| 4265 ctx.regcache = get_thread_regcache (tinfo, 1); | 4474 ctx.regcache = get_thread_regcache (tinfo, 1); |
| 4266 | 4475 |
| 4267 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) | 4476 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) |
| 4268 { | 4477 { |
| 4269 /* Note that we collect fast tracepoints here as well. We'll | 4478 /* Note that we collect fast tracepoints here as well. We'll |
| 4270 step over the fast tracepoint jump later, which avoids the | 4479 step over the fast tracepoint jump later, which avoids the |
| 4271 » double collect. */ | 4480 » double collect. However, we don't collect for static |
| 4272 if (tpoint->enabled && stop_pc == tpoint->address) | 4481 » tracepoints here, because UST markers are compiled in program, |
| 4482 » and probes will be executed in program. So static tracepoints |
| 4483 » are collected there. */ |
| 4484 if (tpoint->enabled && stop_pc == tpoint->address |
| 4485 » && tpoint->type != static_tracepoint) |
| 4273 { | 4486 { |
| 4274 trace_debug ("Thread %s at address of tracepoint %d at 0x%s", | 4487 trace_debug ("Thread %s at address of tracepoint %d at 0x%s", |
| 4275 target_pid_to_str (tinfo->entry.id), | 4488 target_pid_to_str (tinfo->entry.id), |
| 4276 tpoint->number, paddress (tpoint->address)); | 4489 tpoint->number, paddress (tpoint->address)); |
| 4277 | 4490 |
| 4278 /* Test the condition if present, and collect if true. */ | 4491 /* Test the condition if present, and collect if true. */ |
| 4279 if (!tpoint->cond | 4492 if (!tpoint->cond |
| 4280 || (condition_true_at_tracepoint | 4493 || (condition_true_at_tracepoint |
| 4281 ((struct tracepoint_hit_ctx *) &ctx, tpoint))) | 4494 ((struct tracepoint_hit_ctx *) &ctx, tpoint))) |
| 4282 collect_data_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, | 4495 collect_data_at_tracepoint ((struct tracepoint_hit_ctx *) &ctx, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 4302 } | 4515 } |
| 4303 | 4516 |
| 4304 return ret; | 4517 return ret; |
| 4305 } | 4518 } |
| 4306 | 4519 |
| 4307 #endif | 4520 #endif |
| 4308 | 4521 |
| 4309 #if defined IN_PROCESS_AGENT && defined HAVE_UST | 4522 #if defined IN_PROCESS_AGENT && defined HAVE_UST |
| 4310 struct ust_marker_data; | 4523 struct ust_marker_data; |
| 4311 static void collect_ust_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, | 4524 static void collect_ust_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, |
| 4312 CORE_ADDR stop_pc, | |
| 4313 struct tracepoint *tpoint, | |
| 4314 struct traceframe *tframe); | 4525 struct traceframe *tframe); |
| 4315 #endif | 4526 #endif |
| 4316 | 4527 |
| 4317 /* Create a trace frame for the hit of the given tracepoint in the | 4528 /* Create a trace frame for the hit of the given tracepoint in the |
| 4318 given thread. */ | 4529 given thread. */ |
| 4319 | 4530 |
| 4320 static void | 4531 static void |
| 4321 collect_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, CORE_ADDR stop_pc, | 4532 collect_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, CORE_ADDR stop_pc, |
| 4322 struct tracepoint *tpoint) | 4533 struct tracepoint *tpoint) |
| 4323 { | 4534 { |
| 4324 struct traceframe *tframe; | 4535 struct traceframe *tframe; |
| 4325 int acti; | 4536 int acti; |
| 4326 | 4537 |
| 4327 /* Only count it as a hit when we actually collect data. */ | 4538 /* Only count it as a hit when we actually collect data. */ |
| 4328 tpoint->hit_count++; | 4539 tpoint->hit_count++; |
| 4329 | 4540 |
| 4330 /* If we've exceeded a defined pass count, record the event for | 4541 /* If we've exceeded a defined pass count, record the event for |
| 4331 later, and finish the collection for this hit. This test is only | 4542 later, and finish the collection for this hit. This test is only |
| 4332 for nonstepping tracepoints, stepping tracepoints test at the end | 4543 for nonstepping tracepoints, stepping tracepoints test at the end |
| 4333 of their while-stepping loop. */ | 4544 of their while-stepping loop. */ |
| 4334 if (tpoint->pass_count > 0 | 4545 if (tpoint->pass_count > 0 |
| 4335 && tpoint->hit_count >= tpoint->pass_count | 4546 && tpoint->hit_count >= tpoint->pass_count |
| 4336 && tpoint->step_count == 0 | 4547 && tpoint->step_count == 0 |
| 4337 && stopping_tracepoint == NULL) | 4548 && stopping_tracepoint == NULL) |
| 4338 stopping_tracepoint = tpoint; | 4549 stopping_tracepoint = tpoint; |
| 4339 | 4550 |
| 4340 trace_debug ("Making new traceframe for tracepoint %d at 0x%s, hit %ld", | 4551 trace_debug ("Making new traceframe for tracepoint %d at 0x%s, hit %" PRIu64, |
| 4341 tpoint->number, paddress (tpoint->address), tpoint->hit_count); | 4552 tpoint->number, paddress (tpoint->address), tpoint->hit_count); |
| 4342 | 4553 |
| 4343 tframe = add_traceframe (tpoint); | 4554 tframe = add_traceframe (tpoint); |
| 4344 | 4555 |
| 4345 if (tframe) | 4556 if (tframe) |
| 4346 { | 4557 { |
| 4347 for (acti = 0; acti < tpoint->numactions; ++acti) | 4558 for (acti = 0; acti < tpoint->numactions; ++acti) |
| 4348 { | 4559 { |
| 4349 #ifndef IN_PROCESS_AGENT | 4560 #ifndef IN_PROCESS_AGENT |
| 4350 trace_debug ("Tracepoint %d at 0x%s about to do action '%s'", | 4561 trace_debug ("Tracepoint %d at 0x%s about to do action '%s'", |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4367 | 4578 |
| 4368 static void | 4579 static void |
| 4369 collect_data_at_step (struct tracepoint_hit_ctx *ctx, | 4580 collect_data_at_step (struct tracepoint_hit_ctx *ctx, |
| 4370 CORE_ADDR stop_pc, | 4581 CORE_ADDR stop_pc, |
| 4371 struct tracepoint *tpoint, int current_step) | 4582 struct tracepoint *tpoint, int current_step) |
| 4372 { | 4583 { |
| 4373 struct traceframe *tframe; | 4584 struct traceframe *tframe; |
| 4374 int acti; | 4585 int acti; |
| 4375 | 4586 |
| 4376 trace_debug ("Making new step traceframe for " | 4587 trace_debug ("Making new step traceframe for " |
| 4377 » "tracepoint %d at 0x%s, step %d of %ld, hit %ld", | 4588 » "tracepoint %d at 0x%s, step %d of %" PRIu64 ", hit %" PRIu64, |
| 4378 tpoint->number, paddress (tpoint->address), | 4589 tpoint->number, paddress (tpoint->address), |
| 4379 current_step, tpoint->step_count, | 4590 current_step, tpoint->step_count, |
| 4380 tpoint->hit_count); | 4591 tpoint->hit_count); |
| 4381 | 4592 |
| 4382 tframe = add_traceframe (tpoint); | 4593 tframe = add_traceframe (tpoint); |
| 4383 | 4594 |
| 4384 if (tframe) | 4595 if (tframe) |
| 4385 { | 4596 { |
| 4386 for (acti = 0; acti < tpoint->num_step_actions; ++acti) | 4597 for (acti = 0; acti < tpoint->num_step_actions; ++acti) |
| 4387 { | 4598 { |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4513 pointing to the next instruction after the trap, but we | 4724 pointing to the next instruction after the trap, but we |
| 4514 don't want the user or GDB trying to guess whether the | 4725 don't want the user or GDB trying to guess whether the |
| 4515 saved PC needs adjusting; so always record the adjusted | 4726 saved PC needs adjusting; so always record the adjusted |
| 4516 stop_pc. Note that we can't use tpoint->address instead, | 4727 stop_pc. Note that we can't use tpoint->address instead, |
| 4517 since it will be wrong for while-stepping actions. This | 4728 since it will be wrong for while-stepping actions. This |
| 4518 adjustment is a nop for fast tracepoints collected from the | 4729 adjustment is a nop for fast tracepoints collected from the |
| 4519 in-process lib (but not if GDBserver is collecting one | 4730 in-process lib (but not if GDBserver is collecting one |
| 4520 preemptively), since the PC had already been adjusted to | 4731 preemptively), since the PC had already been adjusted to |
| 4521 contain the tracepoint's address by the jump pad. */ | 4732 contain the tracepoint's address by the jump pad. */ |
| 4522 trace_debug ("Storing stop pc (0x%s) in regblock", | 4733 trace_debug ("Storing stop pc (0x%s) in regblock", |
| 4523 » » paddress (tpoint->address)); | 4734 » » paddress (stop_pc)); |
| 4524 | 4735 |
| 4525 /* This changes the regblock, not the thread's | 4736 /* This changes the regblock, not the thread's |
| 4526 regcache. */ | 4737 regcache. */ |
| 4527 regcache_write_pc (&tregcache, stop_pc); | 4738 regcache_write_pc (&tregcache, stop_pc); |
| 4528 #endif | 4739 #endif |
| 4529 } | 4740 } |
| 4530 break; | 4741 break; |
| 4531 case 'X': | 4742 case 'X': |
| 4532 { | 4743 { |
| 4533 struct eval_expr_action *eaction; | 4744 struct eval_expr_action *eaction; |
| 4534 | 4745 |
| 4535 eaction = (struct eval_expr_action *) taction; | 4746 eaction = (struct eval_expr_action *) taction; |
| 4536 | 4747 |
| 4537 trace_debug ("Want to evaluate expression"); | 4748 trace_debug ("Want to evaluate expression"); |
| 4538 | 4749 |
| 4539 » err = eval_agent_expr (ctx, tframe, eaction->expr, NULL); | 4750 » err = eval_tracepoint_agent_expr (ctx, tframe, eaction->expr, NULL); |
| 4540 | 4751 |
| 4541 if (err != expr_eval_no_error) | 4752 if (err != expr_eval_no_error) |
| 4542 { | 4753 { |
| 4543 record_tracepoint_error (tpoint, "action expression", err); | 4754 record_tracepoint_error (tpoint, "action expression", err); |
| 4544 return; | 4755 return; |
| 4545 } | 4756 } |
| 4546 } | 4757 } |
| 4547 break; | 4758 break; |
| 4548 case 'L': | 4759 case 'L': |
| 4549 { | 4760 { |
| 4550 #if defined IN_PROCESS_AGENT && defined HAVE_UST | 4761 #if defined IN_PROCESS_AGENT && defined HAVE_UST |
| 4551 trace_debug ("Want to collect static trace data"); | 4762 trace_debug ("Want to collect static trace data"); |
| 4552 » collect_ust_data_at_tracepoint (ctx, stop_pc, | 4763 » collect_ust_data_at_tracepoint (ctx, tframe); |
| 4553 » » » » » tpoint, tframe); | |
| 4554 #else | 4764 #else |
| 4555 trace_debug ("warning: collecting static trace data, " | 4765 trace_debug ("warning: collecting static trace data, " |
| 4556 "but static tracepoints are not supported"); | 4766 "but static tracepoints are not supported"); |
| 4557 #endif | 4767 #endif |
| 4558 } | 4768 } |
| 4559 break; | 4769 break; |
| 4560 default: | 4770 default: |
| 4561 trace_debug ("unknown trace action '%c', ignoring", taction->type); | 4771 trace_debug ("unknown trace action '%c', ignoring", taction->type); |
| 4562 break; | 4772 break; |
| 4563 } | 4773 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 4582 tracepoints are collected, compared to an alternative where only | 4792 tracepoints are collected, compared to an alternative where only |
| 4583 trap tracepoints are collected on stop, and fast tracepoints on | 4793 trap tracepoints are collected on stop, and fast tracepoints on |
| 4584 resume. When a fast tracepoint is being processed by gdbserver, | 4794 resume. When a fast tracepoint is being processed by gdbserver, |
| 4585 it is always the non-compiled condition expression that is | 4795 it is always the non-compiled condition expression that is |
| 4586 used. */ | 4796 used. */ |
| 4587 #ifdef IN_PROCESS_AGENT | 4797 #ifdef IN_PROCESS_AGENT |
| 4588 if (tpoint->compiled_cond) | 4798 if (tpoint->compiled_cond) |
| 4589 err = ((condfn) (uintptr_t) (tpoint->compiled_cond)) (ctx, &value); | 4799 err = ((condfn) (uintptr_t) (tpoint->compiled_cond)) (ctx, &value); |
| 4590 else | 4800 else |
| 4591 #endif | 4801 #endif |
| 4592 err = eval_agent_expr (ctx, NULL, tpoint->cond, &value); | 4802 err = eval_tracepoint_agent_expr (ctx, NULL, tpoint->cond, &value); |
| 4593 | 4803 |
| 4594 if (err != expr_eval_no_error) | 4804 if (err != expr_eval_no_error) |
| 4595 { | 4805 { |
| 4596 record_tracepoint_error (tpoint, "condition", err); | 4806 record_tracepoint_error (tpoint, "condition", err); |
| 4597 /* The error case must return false. */ | 4807 /* The error case must return false. */ |
| 4598 return 0; | 4808 return 0; |
| 4599 } | 4809 } |
| 4600 | 4810 |
| 4601 trace_debug ("Tracepoint %d at 0x%s condition evals to %s", | 4811 trace_debug ("Tracepoint %d at 0x%s condition evals to %s", |
| 4602 tpoint->number, paddress (tpoint->address), | 4812 tpoint->number, paddress (tpoint->address), |
| 4603 pulongest (value)); | 4813 pulongest (value)); |
| 4604 return (value ? 1 : 0); | 4814 return (value ? 1 : 0); |
| 4605 } | 4815 } |
| 4606 | 4816 |
| 4607 #ifndef IN_PROCESS_AGENT | 4817 /* Evaluates a tracepoint agent expression with context CTX, |
| 4608 | 4818 traceframe TFRAME, agent expression AEXPR and store the |
| 4609 /* The packet form of an agent expression consists of an 'X', number | 4819 result in RSLT. */ |
| 4610 of bytes in expression, a comma, and then the bytes. */ | |
| 4611 | |
| 4612 static struct agent_expr * | |
| 4613 parse_agent_expr (char **actparm) | |
| 4614 { | |
| 4615 char *act = *actparm; | |
| 4616 ULONGEST xlen; | |
| 4617 struct agent_expr *aexpr; | |
| 4618 | |
| 4619 ++act; /* skip the X */ | |
| 4620 act = unpack_varlen_hex (act, &xlen); | |
| 4621 ++act; /* skip a comma */ | |
| 4622 aexpr = xmalloc (sizeof (struct agent_expr)); | |
| 4623 aexpr->length = xlen; | |
| 4624 aexpr->bytes = xmalloc (xlen); | |
| 4625 convert_ascii_to_int (act, aexpr->bytes, xlen); | |
| 4626 *actparm = act + (xlen * 2); | |
| 4627 return aexpr; | |
| 4628 } | |
| 4629 | |
| 4630 /* Convert the bytes of an agent expression back into hex digits, so | |
| 4631 they can be printed or uploaded. This allocates the buffer, | |
| 4632 callers should free when they are done with it. */ | |
| 4633 | |
| 4634 static char * | |
| 4635 unparse_agent_expr (struct agent_expr *aexpr) | |
| 4636 { | |
| 4637 char *rslt; | |
| 4638 | |
| 4639 rslt = xmalloc (2 * aexpr->length + 1); | |
| 4640 convert_int_to_ascii (aexpr->bytes, rslt, aexpr->length); | |
| 4641 return rslt; | |
| 4642 } | |
| 4643 | |
| 4644 #endif | |
| 4645 | |
| 4646 /* A wrapper for gdb_agent_op_names that does some bounds-checking. */ | |
| 4647 | |
| 4648 static const char * | |
| 4649 gdb_agent_op_name (int op) | |
| 4650 { | |
| 4651 if (op < 0 || op >= gdb_agent_op_last || gdb_agent_op_names[op] == NULL) | |
| 4652 return "?undef?"; | |
| 4653 return gdb_agent_op_names[op]; | |
| 4654 } | |
| 4655 | |
| 4656 /* The agent expression evaluator, as specified by the GDB docs. It | |
| 4657 returns 0 if everything went OK, and a nonzero error code | |
| 4658 otherwise. */ | |
| 4659 | 4820 |
| 4660 static enum eval_result_type | 4821 static enum eval_result_type |
| 4661 eval_agent_expr (struct tracepoint_hit_ctx *ctx, | 4822 eval_tracepoint_agent_expr (struct tracepoint_hit_ctx *ctx, |
| 4662 » » struct traceframe *tframe, | 4823 » » » struct traceframe *tframe, |
| 4663 » » struct agent_expr *aexpr, | 4824 » » » struct agent_expr *aexpr, |
| 4664 » » ULONGEST *rslt) | 4825 » » » ULONGEST *rslt) |
| 4665 { | 4826 { |
| 4666 int pc = 0; | 4827 struct regcache *regcache; |
| 4667 #define STACK_MAX 100 | 4828 regcache = get_context_regcache (ctx); |
| 4668 ULONGEST stack[STACK_MAX], top; | |
| 4669 int sp = 0; | |
| 4670 unsigned char op; | |
| 4671 int arg; | |
| 4672 | 4829 |
| 4673 /* This union is a convenient way to convert representations. For | 4830 return gdb_eval_agent_expr (regcache, tframe, aexpr, rslt); |
| 4674 now, assume a standard architecture where the hardware integer | |
| 4675 types have 8, 16, 32, 64 bit types. A more robust solution would | |
| 4676 be to import stdint.h from gnulib. */ | |
| 4677 union | |
| 4678 { | |
| 4679 union | |
| 4680 { | |
| 4681 unsigned char bytes[1]; | |
| 4682 unsigned char val; | |
| 4683 } u8; | |
| 4684 union | |
| 4685 { | |
| 4686 unsigned char bytes[2]; | |
| 4687 unsigned short val; | |
| 4688 } u16; | |
| 4689 union | |
| 4690 { | |
| 4691 unsigned char bytes[4]; | |
| 4692 unsigned int val; | |
| 4693 } u32; | |
| 4694 union | |
| 4695 { | |
| 4696 unsigned char bytes[8]; | |
| 4697 ULONGEST val; | |
| 4698 } u64; | |
| 4699 } cnv; | |
| 4700 | |
| 4701 if (aexpr->length == 0) | |
| 4702 { | |
| 4703 trace_debug ("empty agent expression"); | |
| 4704 return expr_eval_empty_expression; | |
| 4705 } | |
| 4706 | |
| 4707 /* Cache the stack top in its own variable. Much of the time we can | |
| 4708 operate on this variable, rather than dinking with the stack. It | |
| 4709 needs to be copied to the stack when sp changes. */ | |
| 4710 top = 0; | |
| 4711 | |
| 4712 while (1) | |
| 4713 { | |
| 4714 op = aexpr->bytes[pc++]; | |
| 4715 | |
| 4716 trace_debug ("About to interpret byte 0x%x", op); | |
| 4717 | |
| 4718 switch (op) | |
| 4719 » { | |
| 4720 » case gdb_agent_op_add: | |
| 4721 » top += stack[--sp]; | |
| 4722 » break; | |
| 4723 | |
| 4724 » case gdb_agent_op_sub: | |
| 4725 » top = stack[--sp] - top; | |
| 4726 » break; | |
| 4727 | |
| 4728 » case gdb_agent_op_mul: | |
| 4729 » top *= stack[--sp]; | |
| 4730 » break; | |
| 4731 | |
| 4732 » case gdb_agent_op_div_signed: | |
| 4733 » if (top == 0) | |
| 4734 » { | |
| 4735 » trace_debug ("Attempted to divide by zero"); | |
| 4736 » return expr_eval_divide_by_zero; | |
| 4737 » } | |
| 4738 » top = ((LONGEST) stack[--sp]) / ((LONGEST) top); | |
| 4739 » break; | |
| 4740 | |
| 4741 » case gdb_agent_op_div_unsigned: | |
| 4742 » if (top == 0) | |
| 4743 » { | |
| 4744 » trace_debug ("Attempted to divide by zero"); | |
| 4745 » return expr_eval_divide_by_zero; | |
| 4746 » } | |
| 4747 » top = stack[--sp] / top; | |
| 4748 » break; | |
| 4749 | |
| 4750 » case gdb_agent_op_rem_signed: | |
| 4751 » if (top == 0) | |
| 4752 » { | |
| 4753 » trace_debug ("Attempted to divide by zero"); | |
| 4754 » return expr_eval_divide_by_zero; | |
| 4755 » } | |
| 4756 » top = ((LONGEST) stack[--sp]) % ((LONGEST) top); | |
| 4757 » break; | |
| 4758 | |
| 4759 » case gdb_agent_op_rem_unsigned: | |
| 4760 » if (top == 0) | |
| 4761 » { | |
| 4762 » trace_debug ("Attempted to divide by zero"); | |
| 4763 » return expr_eval_divide_by_zero; | |
| 4764 » } | |
| 4765 » top = stack[--sp] % top; | |
| 4766 » break; | |
| 4767 | |
| 4768 » case gdb_agent_op_lsh: | |
| 4769 » top = stack[--sp] << top; | |
| 4770 » break; | |
| 4771 | |
| 4772 » case gdb_agent_op_rsh_signed: | |
| 4773 » top = ((LONGEST) stack[--sp]) >> top; | |
| 4774 » break; | |
| 4775 | |
| 4776 » case gdb_agent_op_rsh_unsigned: | |
| 4777 » top = stack[--sp] >> top; | |
| 4778 » break; | |
| 4779 | |
| 4780 » case gdb_agent_op_trace: | |
| 4781 » agent_mem_read (tframe, | |
| 4782 » » » NULL, (CORE_ADDR) stack[--sp], (ULONGEST) top); | |
| 4783 » if (--sp >= 0) | |
| 4784 » top = stack[sp]; | |
| 4785 » break; | |
| 4786 | |
| 4787 » case gdb_agent_op_trace_quick: | |
| 4788 » arg = aexpr->bytes[pc++]; | |
| 4789 » agent_mem_read (tframe, NULL, (CORE_ADDR) top, (ULONGEST) arg); | |
| 4790 » break; | |
| 4791 | |
| 4792 » case gdb_agent_op_log_not: | |
| 4793 » top = !top; | |
| 4794 » break; | |
| 4795 | |
| 4796 » case gdb_agent_op_bit_and: | |
| 4797 » top &= stack[--sp]; | |
| 4798 » break; | |
| 4799 | |
| 4800 » case gdb_agent_op_bit_or: | |
| 4801 » top |= stack[--sp]; | |
| 4802 » break; | |
| 4803 | |
| 4804 » case gdb_agent_op_bit_xor: | |
| 4805 » top ^= stack[--sp]; | |
| 4806 » break; | |
| 4807 | |
| 4808 » case gdb_agent_op_bit_not: | |
| 4809 » top = ~top; | |
| 4810 » break; | |
| 4811 | |
| 4812 » case gdb_agent_op_equal: | |
| 4813 » top = (stack[--sp] == top); | |
| 4814 » break; | |
| 4815 | |
| 4816 » case gdb_agent_op_less_signed: | |
| 4817 » top = (((LONGEST) stack[--sp]) < ((LONGEST) top)); | |
| 4818 » break; | |
| 4819 | |
| 4820 » case gdb_agent_op_less_unsigned: | |
| 4821 » top = (stack[--sp] < top); | |
| 4822 » break; | |
| 4823 | |
| 4824 » case gdb_agent_op_ext: | |
| 4825 » arg = aexpr->bytes[pc++]; | |
| 4826 » if (arg < (sizeof (LONGEST) * 8)) | |
| 4827 » { | |
| 4828 » LONGEST mask = 1 << (arg - 1); | |
| 4829 » top &= ((LONGEST) 1 << arg) - 1; | |
| 4830 » top = (top ^ mask) - mask; | |
| 4831 » } | |
| 4832 » break; | |
| 4833 | |
| 4834 » case gdb_agent_op_ref8: | |
| 4835 » agent_mem_read (tframe, cnv.u8.bytes, (CORE_ADDR) top, 1); | |
| 4836 » top = cnv.u8.val; | |
| 4837 » break; | |
| 4838 | |
| 4839 » case gdb_agent_op_ref16: | |
| 4840 » agent_mem_read (tframe, cnv.u16.bytes, (CORE_ADDR) top, 2); | |
| 4841 » top = cnv.u16.val; | |
| 4842 » break; | |
| 4843 | |
| 4844 » case gdb_agent_op_ref32: | |
| 4845 » agent_mem_read (tframe, cnv.u32.bytes, (CORE_ADDR) top, 4); | |
| 4846 » top = cnv.u32.val; | |
| 4847 » break; | |
| 4848 | |
| 4849 » case gdb_agent_op_ref64: | |
| 4850 » agent_mem_read (tframe, cnv.u64.bytes, (CORE_ADDR) top, 8); | |
| 4851 » top = cnv.u64.val; | |
| 4852 » break; | |
| 4853 | |
| 4854 » case gdb_agent_op_if_goto: | |
| 4855 » if (top) | |
| 4856 » pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]); | |
| 4857 » else | |
| 4858 » pc += 2; | |
| 4859 » if (--sp >= 0) | |
| 4860 » top = stack[sp]; | |
| 4861 » break; | |
| 4862 | |
| 4863 » case gdb_agent_op_goto: | |
| 4864 » pc = (aexpr->bytes[pc] << 8) + (aexpr->bytes[pc + 1]); | |
| 4865 » break; | |
| 4866 | |
| 4867 » case gdb_agent_op_const8: | |
| 4868 » /* Flush the cached stack top. */ | |
| 4869 » stack[sp++] = top; | |
| 4870 » top = aexpr->bytes[pc++]; | |
| 4871 » break; | |
| 4872 | |
| 4873 » case gdb_agent_op_const16: | |
| 4874 » /* Flush the cached stack top. */ | |
| 4875 » stack[sp++] = top; | |
| 4876 » top = aexpr->bytes[pc++]; | |
| 4877 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4878 » break; | |
| 4879 | |
| 4880 » case gdb_agent_op_const32: | |
| 4881 » /* Flush the cached stack top. */ | |
| 4882 » stack[sp++] = top; | |
| 4883 » top = aexpr->bytes[pc++]; | |
| 4884 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4885 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4886 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4887 » break; | |
| 4888 | |
| 4889 » case gdb_agent_op_const64: | |
| 4890 » /* Flush the cached stack top. */ | |
| 4891 » stack[sp++] = top; | |
| 4892 » top = aexpr->bytes[pc++]; | |
| 4893 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4894 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4895 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4896 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4897 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4898 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4899 » top = (top << 8) + aexpr->bytes[pc++]; | |
| 4900 » break; | |
| 4901 | |
| 4902 » case gdb_agent_op_reg: | |
| 4903 » /* Flush the cached stack top. */ | |
| 4904 » stack[sp++] = top; | |
| 4905 » arg = aexpr->bytes[pc++]; | |
| 4906 » arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 4907 » { | |
| 4908 » int regnum = arg; | |
| 4909 » struct regcache *regcache; | |
| 4910 | |
| 4911 » regcache = get_context_regcache (ctx); | |
| 4912 | |
| 4913 » switch (register_size (regnum)) | |
| 4914 » { | |
| 4915 » case 8: | |
| 4916 » » collect_register (regcache, regnum, cnv.u64.bytes); | |
| 4917 » » top = cnv.u64.val; | |
| 4918 » » break; | |
| 4919 » case 4: | |
| 4920 » » collect_register (regcache, regnum, cnv.u32.bytes); | |
| 4921 » » top = cnv.u32.val; | |
| 4922 » » break; | |
| 4923 » case 2: | |
| 4924 » » collect_register (regcache, regnum, cnv.u16.bytes); | |
| 4925 » » top = cnv.u16.val; | |
| 4926 » » break; | |
| 4927 » case 1: | |
| 4928 » » collect_register (regcache, regnum, cnv.u8.bytes); | |
| 4929 » » top = cnv.u8.val; | |
| 4930 » » break; | |
| 4931 » default: | |
| 4932 » » internal_error (__FILE__, __LINE__, | |
| 4933 » » » » "unhandled register size"); | |
| 4934 » } | |
| 4935 » } | |
| 4936 » break; | |
| 4937 | |
| 4938 » case gdb_agent_op_end: | |
| 4939 » trace_debug ("At end of expression, sp=%d, stack top cache=0x%s", | |
| 4940 » » sp, pulongest (top)); | |
| 4941 » if (rslt) | |
| 4942 » { | |
| 4943 » if (sp <= 0) | |
| 4944 » » { | |
| 4945 » » /* This should be an error */ | |
| 4946 » » trace_debug ("Stack is empty, nothing to return"); | |
| 4947 » » return expr_eval_empty_stack; | |
| 4948 » » } | |
| 4949 » *rslt = top; | |
| 4950 » } | |
| 4951 » return expr_eval_no_error; | |
| 4952 | |
| 4953 » case gdb_agent_op_dup: | |
| 4954 » stack[sp++] = top; | |
| 4955 » break; | |
| 4956 | |
| 4957 » case gdb_agent_op_pop: | |
| 4958 » if (--sp >= 0) | |
| 4959 » top = stack[sp]; | |
| 4960 » break; | |
| 4961 | |
| 4962 » case gdb_agent_op_pick: | |
| 4963 » arg = aexpr->bytes[pc++]; | |
| 4964 » stack[sp] = top; | |
| 4965 » top = stack[sp - arg]; | |
| 4966 » ++sp; | |
| 4967 » break; | |
| 4968 | |
| 4969 » case gdb_agent_op_rot: | |
| 4970 » { | |
| 4971 » ULONGEST tem = stack[sp - 1]; | |
| 4972 | |
| 4973 » stack[sp - 1] = stack[sp - 2]; | |
| 4974 » stack[sp - 2] = top; | |
| 4975 » top = tem; | |
| 4976 » } | |
| 4977 » break; | |
| 4978 | |
| 4979 » case gdb_agent_op_zero_ext: | |
| 4980 » arg = aexpr->bytes[pc++]; | |
| 4981 » if (arg < (sizeof (LONGEST) * 8)) | |
| 4982 » top &= ((LONGEST) 1 << arg) - 1; | |
| 4983 » break; | |
| 4984 | |
| 4985 » case gdb_agent_op_swap: | |
| 4986 » /* Interchange top two stack elements, making sure top gets | |
| 4987 » copied back onto stack. */ | |
| 4988 » stack[sp] = top; | |
| 4989 » top = stack[sp - 1]; | |
| 4990 » stack[sp - 1] = stack[sp]; | |
| 4991 » break; | |
| 4992 | |
| 4993 » case gdb_agent_op_getv: | |
| 4994 » /* Flush the cached stack top. */ | |
| 4995 » stack[sp++] = top; | |
| 4996 » arg = aexpr->bytes[pc++]; | |
| 4997 » arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 4998 » top = get_trace_state_variable_value (arg); | |
| 4999 » break; | |
| 5000 | |
| 5001 » case gdb_agent_op_setv: | |
| 5002 » arg = aexpr->bytes[pc++]; | |
| 5003 » arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 5004 » set_trace_state_variable_value (arg, top); | |
| 5005 » /* Note that we leave the value on the stack, for the | |
| 5006 » benefit of later/enclosing expressions. */ | |
| 5007 » break; | |
| 5008 | |
| 5009 » case gdb_agent_op_tracev: | |
| 5010 » arg = aexpr->bytes[pc++]; | |
| 5011 » arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 5012 » agent_tsv_read (tframe, arg); | |
| 5013 » break; | |
| 5014 | |
| 5015 » case gdb_agent_op_tracenz: | |
| 5016 » agent_mem_read_string (tframe, NULL, (CORE_ADDR) stack[--sp], | |
| 5017 » » » » (ULONGEST) top); | |
| 5018 » if (--sp >= 0) | |
| 5019 » top = stack[sp]; | |
| 5020 » break; | |
| 5021 | |
| 5022 » /* GDB never (currently) generates any of these ops. */ | |
| 5023 » case gdb_agent_op_float: | |
| 5024 » case gdb_agent_op_ref_float: | |
| 5025 » case gdb_agent_op_ref_double: | |
| 5026 » case gdb_agent_op_ref_long_double: | |
| 5027 » case gdb_agent_op_l_to_d: | |
| 5028 » case gdb_agent_op_d_to_l: | |
| 5029 » case gdb_agent_op_trace16: | |
| 5030 » trace_debug ("Agent expression op 0x%x valid, but not handled", | |
| 5031 » » op); | |
| 5032 » /* If ever GDB generates any of these, we don't have the | |
| 5033 » option of ignoring. */ | |
| 5034 » return 1; | |
| 5035 | |
| 5036 » default: | |
| 5037 » trace_debug ("Agent expression op 0x%x not recognized", op); | |
| 5038 » /* Don't struggle on, things will just get worse. */ | |
| 5039 » return expr_eval_unrecognized_opcode; | |
| 5040 » } | |
| 5041 | |
| 5042 /* Check for stack badness. */ | |
| 5043 if (sp >= (STACK_MAX - 1)) | |
| 5044 » { | |
| 5045 » trace_debug ("Expression stack overflow"); | |
| 5046 » return expr_eval_stack_overflow; | |
| 5047 » } | |
| 5048 | |
| 5049 if (sp < 0) | |
| 5050 » { | |
| 5051 » trace_debug ("Expression stack underflow"); | |
| 5052 » return expr_eval_stack_underflow; | |
| 5053 » } | |
| 5054 | |
| 5055 trace_debug ("Op %s -> sp=%d, top=0x%s", | |
| 5056 » » gdb_agent_op_name (op), sp, pulongest (top)); | |
| 5057 } | |
| 5058 } | 4831 } |
| 5059 | 4832 |
| 5060 /* Do memory copies for bytecodes. */ | 4833 /* Do memory copies for bytecodes. */ |
| 5061 /* Do the recording of memory blocks for actions and bytecodes. */ | 4834 /* Do the recording of memory blocks for actions and bytecodes. */ |
| 5062 | 4835 |
| 5063 static int | 4836 int |
| 5064 agent_mem_read (struct traceframe *tframe, | 4837 agent_mem_read (struct traceframe *tframe, |
| 5065 unsigned char *to, CORE_ADDR from, ULONGEST len) | 4838 unsigned char *to, CORE_ADDR from, ULONGEST len) |
| 5066 { | 4839 { |
| 5067 unsigned char *mspace; | 4840 unsigned char *mspace; |
| 5068 ULONGEST remaining = len; | 4841 ULONGEST remaining = len; |
| 5069 unsigned short blocklen; | 4842 unsigned short blocklen; |
| 5070 | 4843 |
| 5071 /* If a 'to' buffer is specified, use it. */ | 4844 /* If a 'to' buffer is specified, use it. */ |
| 5072 if (to != NULL) | 4845 if (to != NULL) |
| 5073 { | 4846 { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5095 mspace += sizeof (blocklen); | 4868 mspace += sizeof (blocklen); |
| 5096 /* Record the memory block proper. */ | 4869 /* Record the memory block proper. */ |
| 5097 read_inferior_memory (from, mspace, blocklen); | 4870 read_inferior_memory (from, mspace, blocklen); |
| 5098 trace_debug ("%d bytes recorded", blocklen); | 4871 trace_debug ("%d bytes recorded", blocklen); |
| 5099 remaining -= blocklen; | 4872 remaining -= blocklen; |
| 5100 from += blocklen; | 4873 from += blocklen; |
| 5101 } | 4874 } |
| 5102 return 0; | 4875 return 0; |
| 5103 } | 4876 } |
| 5104 | 4877 |
| 5105 static int | 4878 int |
| 5106 agent_mem_read_string (struct traceframe *tframe, | 4879 agent_mem_read_string (struct traceframe *tframe, |
| 5107 unsigned char *to, CORE_ADDR from, ULONGEST len) | 4880 unsigned char *to, CORE_ADDR from, ULONGEST len) |
| 5108 { | 4881 { |
| 5109 unsigned char *buf, *mspace; | 4882 unsigned char *buf, *mspace; |
| 5110 ULONGEST remaining = len; | 4883 ULONGEST remaining = len; |
| 5111 unsigned short blocklen, i; | 4884 unsigned short blocklen, i; |
| 5112 | 4885 |
| 5113 /* To save a bit of space, block lengths are 16-bit, so break large | 4886 /* To save a bit of space, block lengths are 16-bit, so break large |
| 5114 requests into multiple blocks. Bordering on overkill for strings, | 4887 requests into multiple blocks. Bordering on overkill for strings, |
| 5115 but it could happen that someone specifies a large max length. */ | 4888 but it could happen that someone specifies a large max length. */ |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5157 memcpy ((void *) mspace, (void *) buf, blocklen); | 4930 memcpy ((void *) mspace, (void *) buf, blocklen); |
| 5158 remaining -= blocklen; | 4931 remaining -= blocklen; |
| 5159 from += blocklen; | 4932 from += blocklen; |
| 5160 xfree (buf); | 4933 xfree (buf); |
| 5161 } | 4934 } |
| 5162 return 0; | 4935 return 0; |
| 5163 } | 4936 } |
| 5164 | 4937 |
| 5165 /* Record the value of a trace state variable. */ | 4938 /* Record the value of a trace state variable. */ |
| 5166 | 4939 |
| 5167 static int | 4940 int |
| 5168 agent_tsv_read (struct traceframe *tframe, int n) | 4941 agent_tsv_read (struct traceframe *tframe, int n) |
| 5169 { | 4942 { |
| 5170 unsigned char *vspace; | 4943 unsigned char *vspace; |
| 5171 LONGEST val; | 4944 LONGEST val; |
| 5172 | 4945 |
| 5173 vspace = add_traceframe_block (tframe, | 4946 vspace = add_traceframe_block (tframe, |
| 5174 1 + sizeof (n) + sizeof (LONGEST)); | 4947 1 + sizeof (n) + sizeof (LONGEST)); |
| 5175 if (vspace == NULL) | 4948 if (vspace == NULL) |
| 5176 return 1; | 4949 return 1; |
| 5177 /* Identify block as a variable. */ | 4950 /* Identify block as a variable. */ |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5950 break; | 5723 break; |
| 5951 } | 5724 } |
| 5952 } | 5725 } |
| 5953 } | 5726 } |
| 5954 } | 5727 } |
| 5955 | 5728 |
| 5956 #endif | 5729 #endif |
| 5957 | 5730 |
| 5958 #ifndef IN_PROCESS_AGENT | 5731 #ifndef IN_PROCESS_AGENT |
| 5959 | 5732 |
| 5960 /* Bytecode compilation. */ | |
| 5961 | |
| 5962 CORE_ADDR current_insn_ptr; | |
| 5963 | |
| 5964 int emit_error; | |
| 5965 | |
| 5966 struct bytecode_address | |
| 5967 { | |
| 5968 int pc; | |
| 5969 CORE_ADDR address; | |
| 5970 int goto_pc; | |
| 5971 /* Offset and size of field to be modified in the goto block. */ | |
| 5972 int from_offset, from_size; | |
| 5973 struct bytecode_address *next; | |
| 5974 } *bytecode_address_table; | |
| 5975 | |
| 5976 CORE_ADDR | 5733 CORE_ADDR |
| 5977 get_raw_reg_func_addr (void) | 5734 get_raw_reg_func_addr (void) |
| 5978 { | 5735 { |
| 5979 return ipa_sym_addrs.addr_get_raw_reg; | 5736 return ipa_sym_addrs.addr_get_raw_reg; |
| 5980 } | 5737 } |
| 5981 | 5738 |
| 5982 static void | 5739 CORE_ADDR |
| 5983 emit_prologue (void) | 5740 get_get_tsv_func_addr (void) |
| 5984 { | 5741 { |
| 5985 target_emit_ops ()->emit_prologue (); | 5742 return ipa_sym_addrs.addr_get_trace_state_variable_value; |
| 5986 } | 5743 } |
| 5987 | 5744 |
| 5988 static void | 5745 CORE_ADDR |
| 5989 emit_epilogue (void) | 5746 get_set_tsv_func_addr (void) |
| 5990 { | 5747 { |
| 5991 target_emit_ops ()->emit_epilogue (); | 5748 return ipa_sym_addrs.addr_set_trace_state_variable_value; |
| 5992 } | 5749 } |
| 5993 | 5750 |
| 5994 static void | 5751 static void |
| 5995 emit_add (void) | |
| 5996 { | |
| 5997 target_emit_ops ()->emit_add (); | |
| 5998 } | |
| 5999 | |
| 6000 static void | |
| 6001 emit_sub (void) | |
| 6002 { | |
| 6003 target_emit_ops ()->emit_sub (); | |
| 6004 } | |
| 6005 | |
| 6006 static void | |
| 6007 emit_mul (void) | |
| 6008 { | |
| 6009 target_emit_ops ()->emit_mul (); | |
| 6010 } | |
| 6011 | |
| 6012 static void | |
| 6013 emit_lsh (void) | |
| 6014 { | |
| 6015 target_emit_ops ()->emit_lsh (); | |
| 6016 } | |
| 6017 | |
| 6018 static void | |
| 6019 emit_rsh_signed (void) | |
| 6020 { | |
| 6021 target_emit_ops ()->emit_rsh_signed (); | |
| 6022 } | |
| 6023 | |
| 6024 static void | |
| 6025 emit_rsh_unsigned (void) | |
| 6026 { | |
| 6027 target_emit_ops ()->emit_rsh_unsigned (); | |
| 6028 } | |
| 6029 | |
| 6030 static void | |
| 6031 emit_ext (int arg) | |
| 6032 { | |
| 6033 target_emit_ops ()->emit_ext (arg); | |
| 6034 } | |
| 6035 | |
| 6036 static void | |
| 6037 emit_log_not (void) | |
| 6038 { | |
| 6039 target_emit_ops ()->emit_log_not (); | |
| 6040 } | |
| 6041 | |
| 6042 static void | |
| 6043 emit_bit_and (void) | |
| 6044 { | |
| 6045 target_emit_ops ()->emit_bit_and (); | |
| 6046 } | |
| 6047 | |
| 6048 static void | |
| 6049 emit_bit_or (void) | |
| 6050 { | |
| 6051 target_emit_ops ()->emit_bit_or (); | |
| 6052 } | |
| 6053 | |
| 6054 static void | |
| 6055 emit_bit_xor (void) | |
| 6056 { | |
| 6057 target_emit_ops ()->emit_bit_xor (); | |
| 6058 } | |
| 6059 | |
| 6060 static void | |
| 6061 emit_bit_not (void) | |
| 6062 { | |
| 6063 target_emit_ops ()->emit_bit_not (); | |
| 6064 } | |
| 6065 | |
| 6066 static void | |
| 6067 emit_equal (void) | |
| 6068 { | |
| 6069 target_emit_ops ()->emit_equal (); | |
| 6070 } | |
| 6071 | |
| 6072 static void | |
| 6073 emit_less_signed (void) | |
| 6074 { | |
| 6075 target_emit_ops ()->emit_less_signed (); | |
| 6076 } | |
| 6077 | |
| 6078 static void | |
| 6079 emit_less_unsigned (void) | |
| 6080 { | |
| 6081 target_emit_ops ()->emit_less_unsigned (); | |
| 6082 } | |
| 6083 | |
| 6084 static void | |
| 6085 emit_ref (int size) | |
| 6086 { | |
| 6087 target_emit_ops ()->emit_ref (size); | |
| 6088 } | |
| 6089 | |
| 6090 static void | |
| 6091 emit_if_goto (int *offset_p, int *size_p) | |
| 6092 { | |
| 6093 target_emit_ops ()->emit_if_goto (offset_p, size_p); | |
| 6094 } | |
| 6095 | |
| 6096 static void | |
| 6097 emit_goto (int *offset_p, int *size_p) | |
| 6098 { | |
| 6099 target_emit_ops ()->emit_goto (offset_p, size_p); | |
| 6100 } | |
| 6101 | |
| 6102 static void | |
| 6103 write_goto_address (CORE_ADDR from, CORE_ADDR to, int size) | |
| 6104 { | |
| 6105 target_emit_ops ()->write_goto_address (from, to, size); | |
| 6106 } | |
| 6107 | |
| 6108 static void | |
| 6109 emit_const (LONGEST num) | |
| 6110 { | |
| 6111 target_emit_ops ()->emit_const (num); | |
| 6112 } | |
| 6113 | |
| 6114 static void | |
| 6115 emit_reg (int reg) | |
| 6116 { | |
| 6117 target_emit_ops ()->emit_reg (reg); | |
| 6118 } | |
| 6119 | |
| 6120 static void | |
| 6121 emit_pop (void) | |
| 6122 { | |
| 6123 target_emit_ops ()->emit_pop (); | |
| 6124 } | |
| 6125 | |
| 6126 static void | |
| 6127 emit_stack_flush (void) | |
| 6128 { | |
| 6129 target_emit_ops ()->emit_stack_flush (); | |
| 6130 } | |
| 6131 | |
| 6132 static void | |
| 6133 emit_zero_ext (int arg) | |
| 6134 { | |
| 6135 target_emit_ops ()->emit_zero_ext (arg); | |
| 6136 } | |
| 6137 | |
| 6138 static void | |
| 6139 emit_swap (void) | |
| 6140 { | |
| 6141 target_emit_ops ()->emit_swap (); | |
| 6142 } | |
| 6143 | |
| 6144 static void | |
| 6145 emit_stack_adjust (int n) | |
| 6146 { | |
| 6147 target_emit_ops ()->emit_stack_adjust (n); | |
| 6148 } | |
| 6149 | |
| 6150 /* FN's prototype is `LONGEST(*fn)(int)'. */ | |
| 6151 | |
| 6152 static void | |
| 6153 emit_int_call_1 (CORE_ADDR fn, int arg1) | |
| 6154 { | |
| 6155 target_emit_ops ()->emit_int_call_1 (fn, arg1); | |
| 6156 } | |
| 6157 | |
| 6158 /* FN's prototype is `void(*fn)(int,LONGEST)'. */ | |
| 6159 | |
| 6160 static void | |
| 6161 emit_void_call_2 (CORE_ADDR fn, int arg1) | |
| 6162 { | |
| 6163 target_emit_ops ()->emit_void_call_2 (fn, arg1); | |
| 6164 } | |
| 6165 | |
| 6166 static void | |
| 6167 emit_eq_goto (int *offset_p, int *size_p) | |
| 6168 { | |
| 6169 target_emit_ops ()->emit_eq_goto (offset_p, size_p); | |
| 6170 } | |
| 6171 | |
| 6172 static void | |
| 6173 emit_ne_goto (int *offset_p, int *size_p) | |
| 6174 { | |
| 6175 target_emit_ops ()->emit_ne_goto (offset_p, size_p); | |
| 6176 } | |
| 6177 | |
| 6178 static void | |
| 6179 emit_lt_goto (int *offset_p, int *size_p) | |
| 6180 { | |
| 6181 target_emit_ops ()->emit_lt_goto (offset_p, size_p); | |
| 6182 } | |
| 6183 | |
| 6184 static void | |
| 6185 emit_ge_goto (int *offset_p, int *size_p) | |
| 6186 { | |
| 6187 target_emit_ops ()->emit_ge_goto (offset_p, size_p); | |
| 6188 } | |
| 6189 | |
| 6190 static void | |
| 6191 emit_gt_goto (int *offset_p, int *size_p) | |
| 6192 { | |
| 6193 target_emit_ops ()->emit_gt_goto (offset_p, size_p); | |
| 6194 } | |
| 6195 | |
| 6196 static void | |
| 6197 emit_le_goto (int *offset_p, int *size_p) | |
| 6198 { | |
| 6199 target_emit_ops ()->emit_le_goto (offset_p, size_p); | |
| 6200 } | |
| 6201 | |
| 6202 static enum eval_result_type compile_bytecodes (struct agent_expr *aexpr); | |
| 6203 | |
| 6204 static void | |
| 6205 compile_tracepoint_condition (struct tracepoint *tpoint, | 5752 compile_tracepoint_condition (struct tracepoint *tpoint, |
| 6206 CORE_ADDR *jump_entry) | 5753 CORE_ADDR *jump_entry) |
| 6207 { | 5754 { |
| 6208 CORE_ADDR entry_point = *jump_entry; | 5755 CORE_ADDR entry_point = *jump_entry; |
| 6209 enum eval_result_type err; | 5756 enum eval_result_type err; |
| 6210 | 5757 |
| 6211 trace_debug ("Starting condition compilation for tracepoint %d\n", | 5758 trace_debug ("Starting condition compilation for tracepoint %d\n", |
| 6212 tpoint->number); | 5759 tpoint->number); |
| 6213 | 5760 |
| 6214 /* Initialize the global pointer to the code being built. */ | 5761 /* Initialize the global pointer to the code being built. */ |
| (...skipping 26 matching lines...) Expand all Loading... |
| 6241 | 5788 |
| 6242 /* Update the code pointer passed in. Note that we do this even if | 5789 /* Update the code pointer passed in. Note that we do this even if |
| 6243 the compile fails, so that we can look at the partial results | 5790 the compile fails, so that we can look at the partial results |
| 6244 instead of letting them be overwritten. */ | 5791 instead of letting them be overwritten. */ |
| 6245 *jump_entry = current_insn_ptr; | 5792 *jump_entry = current_insn_ptr; |
| 6246 | 5793 |
| 6247 /* Leave a gap, to aid dump decipherment. */ | 5794 /* Leave a gap, to aid dump decipherment. */ |
| 6248 *jump_entry += 16; | 5795 *jump_entry += 16; |
| 6249 } | 5796 } |
| 6250 | 5797 |
| 6251 /* Scan an agent expression for any evidence that the given PC is the | |
| 6252 target of a jump bytecode in the expression. */ | |
| 6253 | |
| 6254 int | |
| 6255 is_goto_target (struct agent_expr *aexpr, int pc) | |
| 6256 { | |
| 6257 int i; | |
| 6258 unsigned char op; | |
| 6259 | |
| 6260 for (i = 0; i < aexpr->length; i += 1 + gdb_agent_op_sizes[op]) | |
| 6261 { | |
| 6262 op = aexpr->bytes[i]; | |
| 6263 | |
| 6264 if (op == gdb_agent_op_goto || op == gdb_agent_op_if_goto) | |
| 6265 { | |
| 6266 int target = (aexpr->bytes[i + 1] << 8) + aexpr->bytes[i + 2]; | |
| 6267 if (target == pc) | |
| 6268 return 1; | |
| 6269 } | |
| 6270 } | |
| 6271 | |
| 6272 return 0; | |
| 6273 } | |
| 6274 | |
| 6275 /* Given an agent expression, turn it into native code. */ | |
| 6276 | |
| 6277 static enum eval_result_type | |
| 6278 compile_bytecodes (struct agent_expr *aexpr) | |
| 6279 { | |
| 6280 int pc = 0; | |
| 6281 int done = 0; | |
| 6282 unsigned char op, next_op; | |
| 6283 int arg; | |
| 6284 /* This is only used to build 64-bit value for constants. */ | |
| 6285 ULONGEST top; | |
| 6286 struct bytecode_address *aentry, *aentry2; | |
| 6287 | |
| 6288 #define UNHANDLED \ | |
| 6289 do \ | |
| 6290 { \ | |
| 6291 trace_debug ("Cannot compile op 0x%x\n", op); \ | |
| 6292 return expr_eval_unhandled_opcode; \ | |
| 6293 } while (0) | |
| 6294 | |
| 6295 if (aexpr->length == 0) | |
| 6296 { | |
| 6297 trace_debug ("empty agent expression\n"); | |
| 6298 return expr_eval_empty_expression; | |
| 6299 } | |
| 6300 | |
| 6301 bytecode_address_table = NULL; | |
| 6302 | |
| 6303 while (!done) | |
| 6304 { | |
| 6305 op = aexpr->bytes[pc]; | |
| 6306 | |
| 6307 trace_debug ("About to compile op 0x%x, pc=%d\n", op, pc); | |
| 6308 | |
| 6309 /* Record the compiled-code address of the bytecode, for use by | |
| 6310 jump instructions. */ | |
| 6311 aentry = xmalloc (sizeof (struct bytecode_address)); | |
| 6312 aentry->pc = pc; | |
| 6313 aentry->address = current_insn_ptr; | |
| 6314 aentry->goto_pc = -1; | |
| 6315 aentry->from_offset = aentry->from_size = 0; | |
| 6316 aentry->next = bytecode_address_table; | |
| 6317 bytecode_address_table = aentry; | |
| 6318 | |
| 6319 ++pc; | |
| 6320 | |
| 6321 emit_error = 0; | |
| 6322 | |
| 6323 switch (op) | |
| 6324 { | |
| 6325 case gdb_agent_op_add: | |
| 6326 emit_add (); | |
| 6327 break; | |
| 6328 | |
| 6329 case gdb_agent_op_sub: | |
| 6330 emit_sub (); | |
| 6331 break; | |
| 6332 | |
| 6333 case gdb_agent_op_mul: | |
| 6334 emit_mul (); | |
| 6335 break; | |
| 6336 | |
| 6337 case gdb_agent_op_div_signed: | |
| 6338 UNHANDLED; | |
| 6339 break; | |
| 6340 | |
| 6341 case gdb_agent_op_div_unsigned: | |
| 6342 UNHANDLED; | |
| 6343 break; | |
| 6344 | |
| 6345 case gdb_agent_op_rem_signed: | |
| 6346 UNHANDLED; | |
| 6347 break; | |
| 6348 | |
| 6349 case gdb_agent_op_rem_unsigned: | |
| 6350 UNHANDLED; | |
| 6351 break; | |
| 6352 | |
| 6353 case gdb_agent_op_lsh: | |
| 6354 emit_lsh (); | |
| 6355 break; | |
| 6356 | |
| 6357 case gdb_agent_op_rsh_signed: | |
| 6358 emit_rsh_signed (); | |
| 6359 break; | |
| 6360 | |
| 6361 case gdb_agent_op_rsh_unsigned: | |
| 6362 emit_rsh_unsigned (); | |
| 6363 break; | |
| 6364 | |
| 6365 case gdb_agent_op_trace: | |
| 6366 UNHANDLED; | |
| 6367 break; | |
| 6368 | |
| 6369 case gdb_agent_op_trace_quick: | |
| 6370 UNHANDLED; | |
| 6371 break; | |
| 6372 | |
| 6373 case gdb_agent_op_log_not: | |
| 6374 emit_log_not (); | |
| 6375 break; | |
| 6376 | |
| 6377 case gdb_agent_op_bit_and: | |
| 6378 emit_bit_and (); | |
| 6379 break; | |
| 6380 | |
| 6381 case gdb_agent_op_bit_or: | |
| 6382 emit_bit_or (); | |
| 6383 break; | |
| 6384 | |
| 6385 case gdb_agent_op_bit_xor: | |
| 6386 emit_bit_xor (); | |
| 6387 break; | |
| 6388 | |
| 6389 case gdb_agent_op_bit_not: | |
| 6390 emit_bit_not (); | |
| 6391 break; | |
| 6392 | |
| 6393 case gdb_agent_op_equal: | |
| 6394 next_op = aexpr->bytes[pc]; | |
| 6395 if (next_op == gdb_agent_op_if_goto | |
| 6396 && !is_goto_target (aexpr, pc) | |
| 6397 && target_emit_ops ()->emit_eq_goto) | |
| 6398 { | |
| 6399 trace_debug ("Combining equal & if_goto"); | |
| 6400 pc += 1; | |
| 6401 aentry->pc = pc; | |
| 6402 arg = aexpr->bytes[pc++]; | |
| 6403 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6404 aentry->goto_pc = arg; | |
| 6405 emit_eq_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6406 } | |
| 6407 else if (next_op == gdb_agent_op_log_not | |
| 6408 && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto) | |
| 6409 && !is_goto_target (aexpr, pc + 1) | |
| 6410 && target_emit_ops ()->emit_ne_goto) | |
| 6411 { | |
| 6412 trace_debug ("Combining equal & log_not & if_goto"); | |
| 6413 pc += 2; | |
| 6414 aentry->pc = pc; | |
| 6415 arg = aexpr->bytes[pc++]; | |
| 6416 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6417 aentry->goto_pc = arg; | |
| 6418 emit_ne_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6419 } | |
| 6420 else | |
| 6421 emit_equal (); | |
| 6422 break; | |
| 6423 | |
| 6424 case gdb_agent_op_less_signed: | |
| 6425 next_op = aexpr->bytes[pc]; | |
| 6426 if (next_op == gdb_agent_op_if_goto | |
| 6427 && !is_goto_target (aexpr, pc)) | |
| 6428 { | |
| 6429 trace_debug ("Combining less_signed & if_goto"); | |
| 6430 pc += 1; | |
| 6431 aentry->pc = pc; | |
| 6432 arg = aexpr->bytes[pc++]; | |
| 6433 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6434 aentry->goto_pc = arg; | |
| 6435 emit_lt_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6436 } | |
| 6437 else if (next_op == gdb_agent_op_log_not | |
| 6438 && !is_goto_target (aexpr, pc) | |
| 6439 && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto) | |
| 6440 && !is_goto_target (aexpr, pc + 1)) | |
| 6441 { | |
| 6442 trace_debug ("Combining less_signed & log_not & if_goto"); | |
| 6443 pc += 2; | |
| 6444 aentry->pc = pc; | |
| 6445 arg = aexpr->bytes[pc++]; | |
| 6446 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6447 aentry->goto_pc = arg; | |
| 6448 emit_ge_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6449 } | |
| 6450 else | |
| 6451 emit_less_signed (); | |
| 6452 break; | |
| 6453 | |
| 6454 case gdb_agent_op_less_unsigned: | |
| 6455 emit_less_unsigned (); | |
| 6456 break; | |
| 6457 | |
| 6458 case gdb_agent_op_ext: | |
| 6459 arg = aexpr->bytes[pc++]; | |
| 6460 if (arg < (sizeof (LONGEST) * 8)) | |
| 6461 emit_ext (arg); | |
| 6462 break; | |
| 6463 | |
| 6464 case gdb_agent_op_ref8: | |
| 6465 emit_ref (1); | |
| 6466 break; | |
| 6467 | |
| 6468 case gdb_agent_op_ref16: | |
| 6469 emit_ref (2); | |
| 6470 break; | |
| 6471 | |
| 6472 case gdb_agent_op_ref32: | |
| 6473 emit_ref (4); | |
| 6474 break; | |
| 6475 | |
| 6476 case gdb_agent_op_ref64: | |
| 6477 emit_ref (8); | |
| 6478 break; | |
| 6479 | |
| 6480 case gdb_agent_op_if_goto: | |
| 6481 arg = aexpr->bytes[pc++]; | |
| 6482 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6483 aentry->goto_pc = arg; | |
| 6484 emit_if_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6485 break; | |
| 6486 | |
| 6487 case gdb_agent_op_goto: | |
| 6488 arg = aexpr->bytes[pc++]; | |
| 6489 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6490 aentry->goto_pc = arg; | |
| 6491 emit_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6492 break; | |
| 6493 | |
| 6494 case gdb_agent_op_const8: | |
| 6495 emit_stack_flush (); | |
| 6496 top = aexpr->bytes[pc++]; | |
| 6497 emit_const (top); | |
| 6498 break; | |
| 6499 | |
| 6500 case gdb_agent_op_const16: | |
| 6501 emit_stack_flush (); | |
| 6502 top = aexpr->bytes[pc++]; | |
| 6503 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6504 emit_const (top); | |
| 6505 break; | |
| 6506 | |
| 6507 case gdb_agent_op_const32: | |
| 6508 emit_stack_flush (); | |
| 6509 top = aexpr->bytes[pc++]; | |
| 6510 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6511 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6512 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6513 emit_const (top); | |
| 6514 break; | |
| 6515 | |
| 6516 case gdb_agent_op_const64: | |
| 6517 emit_stack_flush (); | |
| 6518 top = aexpr->bytes[pc++]; | |
| 6519 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6520 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6521 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6522 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6523 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6524 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6525 top = (top << 8) + aexpr->bytes[pc++]; | |
| 6526 emit_const (top); | |
| 6527 break; | |
| 6528 | |
| 6529 case gdb_agent_op_reg: | |
| 6530 emit_stack_flush (); | |
| 6531 arg = aexpr->bytes[pc++]; | |
| 6532 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6533 emit_reg (arg); | |
| 6534 break; | |
| 6535 | |
| 6536 case gdb_agent_op_end: | |
| 6537 trace_debug ("At end of expression\n"); | |
| 6538 | |
| 6539 /* Assume there is one stack element left, and that it is | |
| 6540 cached in "top" where emit_epilogue can get to it. */ | |
| 6541 emit_stack_adjust (1); | |
| 6542 | |
| 6543 done = 1; | |
| 6544 break; | |
| 6545 | |
| 6546 case gdb_agent_op_dup: | |
| 6547 /* In our design, dup is equivalent to stack flushing. */ | |
| 6548 emit_stack_flush (); | |
| 6549 break; | |
| 6550 | |
| 6551 case gdb_agent_op_pop: | |
| 6552 emit_pop (); | |
| 6553 break; | |
| 6554 | |
| 6555 case gdb_agent_op_zero_ext: | |
| 6556 arg = aexpr->bytes[pc++]; | |
| 6557 if (arg < (sizeof (LONGEST) * 8)) | |
| 6558 emit_zero_ext (arg); | |
| 6559 break; | |
| 6560 | |
| 6561 case gdb_agent_op_swap: | |
| 6562 next_op = aexpr->bytes[pc]; | |
| 6563 /* Detect greater-than comparison sequences. */ | |
| 6564 if (next_op == gdb_agent_op_less_signed | |
| 6565 && !is_goto_target (aexpr, pc) | |
| 6566 && (aexpr->bytes[pc + 1] == gdb_agent_op_if_goto) | |
| 6567 && !is_goto_target (aexpr, pc + 1)) | |
| 6568 { | |
| 6569 trace_debug ("Combining swap & less_signed & if_goto"); | |
| 6570 pc += 2; | |
| 6571 aentry->pc = pc; | |
| 6572 arg = aexpr->bytes[pc++]; | |
| 6573 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6574 aentry->goto_pc = arg; | |
| 6575 emit_gt_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6576 } | |
| 6577 else if (next_op == gdb_agent_op_less_signed | |
| 6578 && !is_goto_target (aexpr, pc) | |
| 6579 && (aexpr->bytes[pc + 1] == gdb_agent_op_log_not) | |
| 6580 && !is_goto_target (aexpr, pc + 1) | |
| 6581 && (aexpr->bytes[pc + 2] == gdb_agent_op_if_goto) | |
| 6582 && !is_goto_target (aexpr, pc + 2)) | |
| 6583 { | |
| 6584 trace_debug ("Combining swap & less_signed & log_not & if_goto"); | |
| 6585 pc += 3; | |
| 6586 aentry->pc = pc; | |
| 6587 arg = aexpr->bytes[pc++]; | |
| 6588 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6589 aentry->goto_pc = arg; | |
| 6590 emit_le_goto (&(aentry->from_offset), &(aentry->from_size)); | |
| 6591 } | |
| 6592 else | |
| 6593 emit_swap (); | |
| 6594 break; | |
| 6595 | |
| 6596 case gdb_agent_op_getv: | |
| 6597 emit_stack_flush (); | |
| 6598 arg = aexpr->bytes[pc++]; | |
| 6599 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6600 emit_int_call_1 (ipa_sym_addrs.addr_get_trace_state_variable_value, | |
| 6601 arg); | |
| 6602 break; | |
| 6603 | |
| 6604 case gdb_agent_op_setv: | |
| 6605 arg = aexpr->bytes[pc++]; | |
| 6606 arg = (arg << 8) + aexpr->bytes[pc++]; | |
| 6607 emit_void_call_2 (ipa_sym_addrs.addr_set_trace_state_variable_value, | |
| 6608 arg); | |
| 6609 break; | |
| 6610 | |
| 6611 case gdb_agent_op_tracev: | |
| 6612 UNHANDLED; | |
| 6613 break; | |
| 6614 | |
| 6615 /* GDB never (currently) generates any of these ops. */ | |
| 6616 case gdb_agent_op_float: | |
| 6617 case gdb_agent_op_ref_float: | |
| 6618 case gdb_agent_op_ref_double: | |
| 6619 case gdb_agent_op_ref_long_double: | |
| 6620 case gdb_agent_op_l_to_d: | |
| 6621 case gdb_agent_op_d_to_l: | |
| 6622 case gdb_agent_op_trace16: | |
| 6623 UNHANDLED; | |
| 6624 break; | |
| 6625 | |
| 6626 default: | |
| 6627 trace_debug ("Agent expression op 0x%x not recognized\n", op); | |
| 6628 /* Don't struggle on, things will just get worse. */ | |
| 6629 return expr_eval_unrecognized_opcode; | |
| 6630 } | |
| 6631 | |
| 6632 /* This catches errors that occur in target-specific code | |
| 6633 emission. */ | |
| 6634 if (emit_error) | |
| 6635 { | |
| 6636 trace_debug ("Error %d while emitting code for %s\n", | |
| 6637 emit_error, gdb_agent_op_name (op)); | |
| 6638 return expr_eval_unhandled_opcode; | |
| 6639 } | |
| 6640 | |
| 6641 trace_debug ("Op %s compiled\n", gdb_agent_op_name (op)); | |
| 6642 } | |
| 6643 | |
| 6644 /* Now fill in real addresses as goto destinations. */ | |
| 6645 for (aentry = bytecode_address_table; aentry; aentry = aentry->next) | |
| 6646 { | |
| 6647 int written = 0; | |
| 6648 | |
| 6649 if (aentry->goto_pc < 0) | |
| 6650 continue; | |
| 6651 | |
| 6652 /* Find the location that we are going to, and call back into | |
| 6653 target-specific code to write the actual address or | |
| 6654 displacement. */ | |
| 6655 for (aentry2 = bytecode_address_table; aentry2; aentry2 = aentry2->next) | |
| 6656 { | |
| 6657 if (aentry2->pc == aentry->goto_pc) | |
| 6658 { | |
| 6659 trace_debug ("Want to jump from %s to %s\n", | |
| 6660 paddress (aentry->address), | |
| 6661 paddress (aentry2->address)); | |
| 6662 write_goto_address (aentry->address + aentry->from_offset, | |
| 6663 aentry2->address, aentry->from_size); | |
| 6664 written = 1; | |
| 6665 break; | |
| 6666 } | |
| 6667 } | |
| 6668 | |
| 6669 /* Error out if we didn't find a destination. */ | |
| 6670 if (!written) | |
| 6671 { | |
| 6672 trace_debug ("Destination of goto %d not found\n", | |
| 6673 aentry->goto_pc); | |
| 6674 return expr_eval_invalid_goto; | |
| 6675 } | |
| 6676 } | |
| 6677 | |
| 6678 return expr_eval_no_error; | |
| 6679 } | |
| 6680 | |
| 6681 /* We'll need to adjust these when we consider bi-arch setups, and big | 5798 /* We'll need to adjust these when we consider bi-arch setups, and big |
| 6682 endian machines. */ | 5799 endian machines. */ |
| 6683 | 5800 |
| 6684 static int | 5801 static int |
| 6685 write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr) | 5802 write_inferior_data_ptr (CORE_ADDR where, CORE_ADDR ptr) |
| 6686 { | 5803 { |
| 6687 return write_inferior_memory (where, | 5804 return write_inferior_memory (where, |
| 6688 (unsigned char *) &ptr, sizeof (void *)); | 5805 (unsigned char *) &ptr, sizeof (void *)); |
| 6689 } | 5806 } |
| 6690 | 5807 |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6801 /* The pointers array. */ | 5918 /* The pointers array. */ |
| 6802 actions_array | 5919 actions_array |
| 6803 = target_malloc (sizeof (*tpoint->actions) * tpoint->numactions); | 5920 = target_malloc (sizeof (*tpoint->actions) * tpoint->numactions); |
| 6804 write_inferior_data_ptr (tpptr + offsetof (struct tracepoint, | 5921 write_inferior_data_ptr (tpptr + offsetof (struct tracepoint, |
| 6805 actions), | 5922 actions), |
| 6806 actions_array); | 5923 actions_array); |
| 6807 | 5924 |
| 6808 /* Now for each pointer, download the action. */ | 5925 /* Now for each pointer, download the action. */ |
| 6809 for (i = 0; i < tpoint->numactions; i++) | 5926 for (i = 0; i < tpoint->numactions; i++) |
| 6810 { | 5927 { |
| 6811 CORE_ADDR ipa_action = 0; | |
| 6812 struct tracepoint_action *action = tpoint->actions[i]; | 5928 struct tracepoint_action *action = tpoint->actions[i]; |
| 6813 | 5929 » CORE_ADDR ipa_action = action->ops->download (action); |
| 6814 » switch (action->type) | |
| 6815 » { | |
| 6816 » case 'M': | |
| 6817 » ipa_action | |
| 6818 » » = target_malloc (sizeof (struct collect_memory_action)); | |
| 6819 » write_inferior_memory (ipa_action, | |
| 6820 » » » » (unsigned char *) action, | |
| 6821 » » » » sizeof (struct collect_memory_action)); | |
| 6822 » break; | |
| 6823 » case 'R': | |
| 6824 » ipa_action | |
| 6825 » » = target_malloc (sizeof (struct collect_registers_action)); | |
| 6826 » write_inferior_memory (ipa_action, | |
| 6827 » » » » (unsigned char *) action, | |
| 6828 » » » » sizeof (struct collect_registers_action)); | |
| 6829 » break; | |
| 6830 » case 'X': | |
| 6831 » { | |
| 6832 » » CORE_ADDR expr; | |
| 6833 » » struct eval_expr_action *eaction | |
| 6834 » » = (struct eval_expr_action *) action; | |
| 6835 | |
| 6836 » » ipa_action = target_malloc (sizeof (*eaction)); | |
| 6837 » » write_inferior_memory (ipa_action, | |
| 6838 » » » » (unsigned char *) eaction, | |
| 6839 » » » » sizeof (*eaction)); | |
| 6840 | |
| 6841 » » expr = download_agent_expr (eaction->expr); | |
| 6842 » » write_inferior_data_ptr | |
| 6843 » » (ipa_action + offsetof (struct eval_expr_action, expr), | |
| 6844 » » expr); | |
| 6845 » » break; | |
| 6846 » } | |
| 6847 » case 'L': | |
| 6848 » ipa_action = target_malloc | |
| 6849 » » (sizeof (struct collect_static_trace_data_action)); | |
| 6850 » write_inferior_memory | |
| 6851 » » (ipa_action, | |
| 6852 » » (unsigned char *) action, | |
| 6853 » » sizeof (struct collect_static_trace_data_action)); | |
| 6854 » break; | |
| 6855 » default: | |
| 6856 » trace_debug ("unknown trace action '%c', ignoring", | |
| 6857 » » » action->type); | |
| 6858 » break; | |
| 6859 » } | |
| 6860 | 5930 |
| 6861 if (ipa_action != 0) | 5931 if (ipa_action != 0) |
| 6862 write_inferior_data_ptr | 5932 write_inferior_data_ptr |
| 6863 (actions_array + i * sizeof (sizeof (*tpoint->actions)), | 5933 (actions_array + i * sizeof (sizeof (*tpoint->actions)), |
| 6864 ipa_action); | 5934 ipa_action); |
| 6865 } | 5935 } |
| 6866 } | 5936 } |
| 6867 } | 5937 } |
| 6868 | 5938 |
| 5939 #define IPA_PROTO_FAST_TRACE_FLAG 0 |
| 5940 #define IPA_PROTO_FAST_TRACE_ADDR_ON_TARGET 2 |
| 5941 #define IPA_PROTO_FAST_TRACE_JUMP_PAD 10 |
| 5942 #define IPA_PROTO_FAST_TRACE_FJUMP_SIZE 18 |
| 5943 #define IPA_PROTO_FAST_TRACE_FJUMP_INSN 22 |
| 5944 |
| 5945 /* Send a command to agent to download and install tracepoint TPOINT. */ |
| 5946 |
| 5947 static int |
| 5948 tracepoint_send_agent (struct tracepoint *tpoint) |
| 5949 { |
| 5950 char buf[IPA_CMD_BUF_SIZE]; |
| 5951 char *p; |
| 5952 int i, ret; |
| 5953 |
| 5954 p = buf; |
| 5955 strcpy (p, "FastTrace:"); |
| 5956 p += 10; |
| 5957 |
| 5958 COPY_FIELD_TO_BUF (p, tpoint, number); |
| 5959 COPY_FIELD_TO_BUF (p, tpoint, address); |
| 5960 COPY_FIELD_TO_BUF (p, tpoint, type); |
| 5961 COPY_FIELD_TO_BUF (p, tpoint, enabled); |
| 5962 COPY_FIELD_TO_BUF (p, tpoint, step_count); |
| 5963 COPY_FIELD_TO_BUF (p, tpoint, pass_count); |
| 5964 COPY_FIELD_TO_BUF (p, tpoint, numactions); |
| 5965 COPY_FIELD_TO_BUF (p, tpoint, hit_count); |
| 5966 COPY_FIELD_TO_BUF (p, tpoint, traceframe_usage); |
| 5967 COPY_FIELD_TO_BUF (p, tpoint, compiled_cond); |
| 5968 COPY_FIELD_TO_BUF (p, tpoint, orig_size); |
| 5969 |
| 5970 /* condition */ |
| 5971 p = agent_expr_send (p, tpoint->cond); |
| 5972 |
| 5973 /* tracepoint_action */ |
| 5974 for (i = 0; i < tpoint->numactions; i++) |
| 5975 { |
| 5976 struct tracepoint_action *action = tpoint->actions[i]; |
| 5977 |
| 5978 p[0] = action->type; |
| 5979 p = action->ops->send (&p[1], action); |
| 5980 } |
| 5981 |
| 5982 get_jump_space_head (); |
| 5983 /* Copy the value of GDB_JUMP_PAD_HEAD to command buffer, so that |
| 5984 agent can use jump pad from it. */ |
| 5985 if (tpoint->type == fast_tracepoint) |
| 5986 { |
| 5987 memcpy (p, &gdb_jump_pad_head, 8); |
| 5988 p += 8; |
| 5989 } |
| 5990 |
| 5991 ret = run_inferior_command (buf, (int) (ptrdiff_t) (p - buf)); |
| 5992 if (ret) |
| 5993 return ret; |
| 5994 |
| 5995 if (strncmp (buf, "OK", 2) != 0) |
| 5996 return 1; |
| 5997 |
| 5998 /* The value of tracepoint's target address is stored in BUF. */ |
| 5999 memcpy (&tpoint->obj_addr_on_target, |
| 6000 &buf[IPA_PROTO_FAST_TRACE_ADDR_ON_TARGET], 8); |
| 6001 |
| 6002 if (tpoint->type == fast_tracepoint) |
| 6003 { |
| 6004 unsigned char *insn |
| 6005 = (unsigned char *) &buf[IPA_PROTO_FAST_TRACE_FJUMP_INSN]; |
| 6006 int fjump_size; |
| 6007 |
| 6008 trace_debug ("agent: read from cmd_buf 0x%x 0x%x\n", |
| 6009 (unsigned int) tpoint->obj_addr_on_target, |
| 6010 (unsigned int) gdb_jump_pad_head); |
| 6011 |
| 6012 memcpy (&gdb_jump_pad_head, &buf[IPA_PROTO_FAST_TRACE_JUMP_PAD], 8); |
| 6013 |
| 6014 /* This has been done in agent. We should also set up record for it. */ |
| 6015 memcpy (&fjump_size, &buf[IPA_PROTO_FAST_TRACE_FJUMP_SIZE], 4); |
| 6016 /* Wire it in. */ |
| 6017 tpoint->handle |
| 6018 = set_fast_tracepoint_jump (tpoint->address, insn, fjump_size); |
| 6019 } |
| 6020 |
| 6021 return 0; |
| 6022 } |
| 6023 |
| 6869 static void | 6024 static void |
| 6870 download_tracepoint (struct tracepoint *tpoint) | 6025 download_tracepoint (struct tracepoint *tpoint) |
| 6871 { | 6026 { |
| 6872 struct tracepoint *tp, *tp_prev; | 6027 struct tracepoint *tp, *tp_prev; |
| 6873 | 6028 |
| 6874 if (tpoint->type != fast_tracepoint | 6029 if (tpoint->type != fast_tracepoint |
| 6875 && tpoint->type != static_tracepoint) | 6030 && tpoint->type != static_tracepoint) |
| 6876 return; | 6031 return; |
| 6877 | 6032 |
| 6878 download_tracepoint_1 (tpoint); | 6033 download_tracepoint_1 (tpoint); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 6907 } | 6062 } |
| 6908 else | 6063 else |
| 6909 /* First object in list, set the head pointer in the | 6064 /* First object in list, set the head pointer in the |
| 6910 inferior. */ | 6065 inferior. */ |
| 6911 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, | 6066 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, |
| 6912 tpoint->obj_addr_on_target); | 6067 tpoint->obj_addr_on_target); |
| 6913 | 6068 |
| 6914 } | 6069 } |
| 6915 | 6070 |
| 6916 static void | 6071 static void |
| 6917 download_tracepoints (void) | |
| 6918 { | |
| 6919 CORE_ADDR tpptr = 0, prev_tpptr = 0; | |
| 6920 struct tracepoint *tpoint; | |
| 6921 | |
| 6922 /* Start out empty. */ | |
| 6923 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, 0); | |
| 6924 | |
| 6925 for (tpoint = tracepoints; tpoint; tpoint = tpoint->next) | |
| 6926 { | |
| 6927 if (tpoint->type != fast_tracepoint | |
| 6928 && tpoint->type != static_tracepoint) | |
| 6929 continue; | |
| 6930 | |
| 6931 prev_tpptr = tpptr; | |
| 6932 | |
| 6933 download_tracepoint_1 (tpoint); | |
| 6934 | |
| 6935 tpptr = tpoint->obj_addr_on_target; | |
| 6936 | |
| 6937 if (tpoint == tracepoints) | |
| 6938 { | |
| 6939 /* First object in list, set the head pointer in the | |
| 6940 inferior. */ | |
| 6941 write_inferior_data_ptr (ipa_sym_addrs.addr_tracepoints, tpptr); | |
| 6942 } | |
| 6943 else | |
| 6944 { | |
| 6945 write_inferior_data_ptr (prev_tpptr + offsetof (struct tracepoint, | |
| 6946 next), | |
| 6947 tpptr); | |
| 6948 } | |
| 6949 } | |
| 6950 } | |
| 6951 | |
| 6952 static void | |
| 6953 download_trace_state_variables (void) | 6072 download_trace_state_variables (void) |
| 6954 { | 6073 { |
| 6955 CORE_ADDR ptr = 0, prev_ptr = 0; | 6074 CORE_ADDR ptr = 0, prev_ptr = 0; |
| 6956 struct trace_state_variable *tsv; | 6075 struct trace_state_variable *tsv; |
| 6957 | 6076 |
| 6958 /* Start out empty. */ | 6077 /* Start out empty. */ |
| 6959 write_inferior_data_ptr (ipa_sym_addrs.addr_trace_state_variables, 0); | 6078 write_inferior_data_ptr (ipa_sym_addrs.addr_trace_state_variables, 0); |
| 6960 | 6079 |
| 6961 for (tsv = trace_state_variables; tsv != NULL; tsv = tsv->next) | 6080 for (tsv = trace_state_variables; tsv != NULL; tsv = tsv->next) |
| 6962 { | 6081 { |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7278 unpause_all (1); | 6397 unpause_all (1); |
| 7279 | 6398 |
| 7280 if (trace_buffer_is_full) | 6399 if (trace_buffer_is_full) |
| 7281 stop_tracing (); | 6400 stop_tracing (); |
| 7282 } | 6401 } |
| 7283 #endif | 6402 #endif |
| 7284 | 6403 |
| 7285 #ifdef IN_PROCESS_AGENT | 6404 #ifdef IN_PROCESS_AGENT |
| 7286 | 6405 |
| 7287 IP_AGENT_EXPORT int ust_loaded; | 6406 IP_AGENT_EXPORT int ust_loaded; |
| 7288 IP_AGENT_EXPORT char cmd_buf[CMD_BUF_SIZE]; | 6407 IP_AGENT_EXPORT char cmd_buf[IPA_CMD_BUF_SIZE]; |
| 7289 | 6408 |
| 7290 #ifdef HAVE_UST | 6409 #ifdef HAVE_UST |
| 7291 | 6410 |
| 7292 /* Static tracepoints. */ | 6411 /* Static tracepoints. */ |
| 7293 | 6412 |
| 7294 /* UST puts a "struct tracepoint" in the global namespace, which | 6413 /* UST puts a "struct tracepoint" in the global namespace, which |
| 7295 conflicts with our tracepoint. Arguably, being a library, it | 6414 conflicts with our tracepoint. Arguably, being a library, it |
| 7296 shouldn't take ownership of such a generic name. We work around it | 6415 shouldn't take ownership of such a generic name. We work around it |
| 7297 here. */ | 6416 here. */ |
| 7298 #define tracepoint ust_tracepoint | 6417 #define tracepoint ust_tracepoint |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7471 tracing library by the user, at the time of the tracepoint marker | 6590 tracing library by the user, at the time of the tracepoint marker |
| 7472 call. E.g., in the UST marker call: | 6591 call. E.g., in the UST marker call: |
| 7473 | 6592 |
| 7474 trace_mark (ust, bar33, "str %s", "FOOBAZ"); | 6593 trace_mark (ust, bar33, "str %s", "FOOBAZ"); |
| 7475 | 6594 |
| 7476 the collected data is "str FOOBAZ". | 6595 the collected data is "str FOOBAZ". |
| 7477 */ | 6596 */ |
| 7478 | 6597 |
| 7479 static void | 6598 static void |
| 7480 collect_ust_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, | 6599 collect_ust_data_at_tracepoint (struct tracepoint_hit_ctx *ctx, |
| 7481 CORE_ADDR stop_pc, | |
| 7482 struct tracepoint *tpoint, | |
| 7483 struct traceframe *tframe) | 6600 struct traceframe *tframe) |
| 7484 { | 6601 { |
| 7485 struct static_tracepoint_ctx *umd = (struct static_tracepoint_ctx *) ctx; | 6602 struct static_tracepoint_ctx *umd = (struct static_tracepoint_ctx *) ctx; |
| 7486 unsigned char *bufspace; | 6603 unsigned char *bufspace; |
| 7487 int size; | 6604 int size; |
| 7488 va_list copy; | 6605 va_list copy; |
| 7489 unsigned short blocklen; | 6606 unsigned short blocklen; |
| 7490 | 6607 |
| 7491 if (umd == NULL) | 6608 if (umd == NULL) |
| 7492 { | 6609 { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7529 static struct ltt_available_probe gdb_ust_probe = | 6646 static struct ltt_available_probe gdb_ust_probe = |
| 7530 { | 6647 { |
| 7531 GDB_PROBE_NAME, | 6648 GDB_PROBE_NAME, |
| 7532 NULL, | 6649 NULL, |
| 7533 gdb_probe, | 6650 gdb_probe, |
| 7534 }; | 6651 }; |
| 7535 | 6652 |
| 7536 #endif /* HAVE_UST */ | 6653 #endif /* HAVE_UST */ |
| 7537 #endif /* IN_PROCESS_AGENT */ | 6654 #endif /* IN_PROCESS_AGENT */ |
| 7538 | 6655 |
| 7539 #ifdef HAVE_UST | |
| 7540 | |
| 7541 #include <sys/socket.h> | |
| 7542 #include <sys/un.h> | |
| 7543 | |
| 7544 #ifndef UNIX_PATH_MAX | |
| 7545 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) | |
| 7546 #endif | |
| 7547 | |
| 7548 /* Where we put the socked used for synchronization. */ | |
| 7549 #define SOCK_DIR P_tmpdir | |
| 7550 | |
| 7551 #endif /* HAVE_UST */ | |
| 7552 | |
| 7553 #ifndef IN_PROCESS_AGENT | 6656 #ifndef IN_PROCESS_AGENT |
| 7554 | 6657 |
| 7555 #ifdef HAVE_UST | |
| 7556 | |
| 7557 static int | |
| 7558 gdb_ust_connect_sync_socket (int pid) | |
| 7559 { | |
| 7560 struct sockaddr_un addr; | |
| 7561 int res, fd; | |
| 7562 char path[UNIX_PATH_MAX]; | |
| 7563 | |
| 7564 res = xsnprintf (path, UNIX_PATH_MAX, "%s/gdb_ust%d", SOCK_DIR, pid); | |
| 7565 if (res >= UNIX_PATH_MAX) | |
| 7566 { | |
| 7567 trace_debug ("string overflow allocating socket name"); | |
| 7568 return -1; | |
| 7569 } | |
| 7570 | |
| 7571 res = fd = socket (PF_UNIX, SOCK_STREAM, 0); | |
| 7572 if (res == -1) | |
| 7573 { | |
| 7574 warning ("error opening sync socket: %s\n", strerror (errno)); | |
| 7575 return -1; | |
| 7576 } | |
| 7577 | |
| 7578 addr.sun_family = AF_UNIX; | |
| 7579 | |
| 7580 res = xsnprintf (addr.sun_path, UNIX_PATH_MAX, "%s", path); | |
| 7581 if (res >= UNIX_PATH_MAX) | |
| 7582 { | |
| 7583 warning ("string overflow allocating socket name\n"); | |
| 7584 close (fd); | |
| 7585 return -1; | |
| 7586 } | |
| 7587 | |
| 7588 res = connect (fd, (struct sockaddr *) &addr, sizeof (addr)); | |
| 7589 if (res == -1) | |
| 7590 { | |
| 7591 warning ("error connecting sync socket (%s): %s. " | |
| 7592 "Make sure the directory exists and that it is writable.", | |
| 7593 path, strerror (errno)); | |
| 7594 close (fd); | |
| 7595 return -1; | |
| 7596 } | |
| 7597 | |
| 7598 return fd; | |
| 7599 } | |
| 7600 | |
| 7601 /* Resume thread PTID. */ | |
| 7602 | |
| 7603 static void | |
| 7604 resume_thread (ptid_t ptid) | |
| 7605 { | |
| 7606 struct thread_resume resume_info; | |
| 7607 | |
| 7608 resume_info.thread = ptid; | |
| 7609 resume_info.kind = resume_continue; | |
| 7610 resume_info.sig = TARGET_SIGNAL_0; | |
| 7611 (*the_target->resume) (&resume_info, 1); | |
| 7612 } | |
| 7613 | |
| 7614 /* Stop thread PTID. */ | |
| 7615 | |
| 7616 static void | |
| 7617 stop_thread (ptid_t ptid) | |
| 7618 { | |
| 7619 struct thread_resume resume_info; | |
| 7620 | |
| 7621 resume_info.thread = ptid; | |
| 7622 resume_info.kind = resume_stop; | |
| 7623 resume_info.sig = TARGET_SIGNAL_0; | |
| 7624 (*the_target->resume) (&resume_info, 1); | |
| 7625 } | |
| 7626 | |
| 7627 /* Ask the in-process agent to run a command. Since we don't want to | 6658 /* Ask the in-process agent to run a command. Since we don't want to |
| 7628 have to handle the IPA hitting breakpoints while running the | 6659 have to handle the IPA hitting breakpoints while running the |
| 7629 command, we pause all threads, remove all breakpoints, and then set | 6660 command, we pause all threads, remove all breakpoints, and then set |
| 7630 the helper thread re-running. We communicate with the helper | 6661 the helper thread re-running. We communicate with the helper |
| 7631 thread by means of direct memory xfering, and a socket for | 6662 thread by means of direct memory xfering, and a socket for |
| 7632 synchronization. */ | 6663 synchronization. */ |
| 7633 | 6664 |
| 7634 static int | 6665 static int |
| 7635 run_inferior_command (char *cmd) | 6666 run_inferior_command (char *cmd, int len) |
| 7636 { | 6667 { |
| 7637 int err = -1; | 6668 int err = -1; |
| 7638 int fd = -1; | |
| 7639 int pid = ptid_get_pid (current_inferior->entry.id); | 6669 int pid = ptid_get_pid (current_inferior->entry.id); |
| 7640 int tid; | |
| 7641 ptid_t ptid = null_ptid; | |
| 7642 | 6670 |
| 7643 trace_debug ("run_inferior_command: running: %s", cmd); | 6671 trace_debug ("run_inferior_command: running: %s", cmd); |
| 7644 | 6672 |
| 7645 pause_all (0); | 6673 pause_all (0); |
| 7646 uninsert_all_breakpoints (); | 6674 uninsert_all_breakpoints (); |
| 7647 | 6675 |
| 7648 if (read_inferior_integer (ipa_sym_addrs.addr_helper_thread_id, &tid)) | 6676 err = agent_run_command (pid, (const char *) cmd, len); |
| 7649 { | |
| 7650 warning ("Error reading helper thread's id in lib"); | |
| 7651 goto out; | |
| 7652 } | |
| 7653 | |
| 7654 if (tid == 0) | |
| 7655 { | |
| 7656 warning ("helper thread not initialized yet"); | |
| 7657 goto out; | |
| 7658 } | |
| 7659 | |
| 7660 if (write_inferior_memory (ipa_sym_addrs.addr_cmd_buf, | |
| 7661 » » » (unsigned char *) cmd, strlen (cmd) + 1)) | |
| 7662 { | |
| 7663 warning ("Error writing command"); | |
| 7664 goto out; | |
| 7665 } | |
| 7666 | |
| 7667 ptid = ptid_build (pid, tid, 0); | |
| 7668 | |
| 7669 resume_thread (ptid); | |
| 7670 | |
| 7671 fd = gdb_ust_connect_sync_socket (pid); | |
| 7672 if (fd >= 0) | |
| 7673 { | |
| 7674 char buf[1] = ""; | |
| 7675 int ret; | |
| 7676 | |
| 7677 trace_debug ("signalling helper thread"); | |
| 7678 | |
| 7679 do | |
| 7680 » { | |
| 7681 » ret = write (fd, buf, 1); | |
| 7682 » } while (ret == -1 && errno == EINTR); | |
| 7683 | |
| 7684 trace_debug ("waiting for helper thread's response"); | |
| 7685 | |
| 7686 do | |
| 7687 » { | |
| 7688 » ret = read (fd, buf, 1); | |
| 7689 » } while (ret == -1 && errno == EINTR); | |
| 7690 | |
| 7691 close (fd); | |
| 7692 | |
| 7693 trace_debug ("helper thread's response received"); | |
| 7694 } | |
| 7695 | |
| 7696 out: | |
| 7697 | |
| 7698 /* Need to read response with the inferior stopped. */ | |
| 7699 if (!ptid_equal (ptid, null_ptid)) | |
| 7700 { | |
| 7701 int was_non_stop = non_stop; | |
| 7702 struct target_waitstatus status; | |
| 7703 | |
| 7704 stop_thread (ptid); | |
| 7705 non_stop = 1; | |
| 7706 mywait (ptid, &status, 0, 0); | |
| 7707 non_stop = was_non_stop; | |
| 7708 } | |
| 7709 | |
| 7710 if (fd >= 0) | |
| 7711 { | |
| 7712 if (read_inferior_memory (ipa_sym_addrs.addr_cmd_buf, | |
| 7713 » » » » (unsigned char *) cmd, CMD_BUF_SIZE)) | |
| 7714 » { | |
| 7715 » warning ("Error reading command response"); | |
| 7716 » } | |
| 7717 else | |
| 7718 » { | |
| 7719 » err = 0; | |
| 7720 » trace_debug ("run_inferior_command: response: %s", cmd); | |
| 7721 » } | |
| 7722 } | |
| 7723 | 6677 |
| 7724 reinsert_all_breakpoints (); | 6678 reinsert_all_breakpoints (); |
| 7725 unpause_all (0); | 6679 unpause_all (0); |
| 7726 | 6680 |
| 7727 return err; | 6681 return err; |
| 7728 } | 6682 } |
| 7729 | 6683 |
| 7730 #else /* HAVE_UST */ | 6684 #else /* !IN_PROCESS_AGENT */ |
| 7731 | 6685 |
| 7732 static int | 6686 #include <sys/socket.h> |
| 7733 run_inferior_command (char *cmd) | 6687 #include <sys/un.h> |
| 7734 { | |
| 7735 return -1; | |
| 7736 } | |
| 7737 | 6688 |
| 7738 #endif /* HAVE_UST */ | 6689 #ifndef UNIX_PATH_MAX |
| 6690 #define UNIX_PATH_MAX sizeof(((struct sockaddr_un *) NULL)->sun_path) |
| 6691 #endif |
| 7739 | 6692 |
| 7740 #else /* !IN_PROCESS_AGENT */ | 6693 /* Where we put the socked used for synchronization. */ |
| 6694 #define SOCK_DIR P_tmpdir |
| 7741 | 6695 |
| 7742 /* Thread ID of the helper thread. GDBserver reads this to know which | 6696 /* Thread ID of the helper thread. GDBserver reads this to know which |
| 7743 is the help thread. This is an LWP id on Linux. */ | 6697 is the help thread. This is an LWP id on Linux. */ |
| 7744 int helper_thread_id; | 6698 int helper_thread_id; |
| 7745 | 6699 |
| 7746 #ifdef HAVE_UST | |
| 7747 | |
| 7748 static int | 6700 static int |
| 7749 init_named_socket (const char *name) | 6701 init_named_socket (const char *name) |
| 7750 { | 6702 { |
| 7751 int result, fd; | 6703 int result, fd; |
| 7752 struct sockaddr_un addr; | 6704 struct sockaddr_un addr; |
| 7753 | 6705 |
| 7754 result = fd = socket (PF_UNIX, SOCK_STREAM, 0); | 6706 result = fd = socket (PF_UNIX, SOCK_STREAM, 0); |
| 7755 if (result == -1) | 6707 if (result == -1) |
| 7756 { | 6708 { |
| 7757 warning ("socket creation failed: %s", strerror (errno)); | 6709 warning ("socket creation failed: %s", strerror (errno)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7790 { | 6742 { |
| 7791 warning ("listen: %s", strerror (errno)); | 6743 warning ("listen: %s", strerror (errno)); |
| 7792 close (fd); | 6744 close (fd); |
| 7793 return -1; | 6745 return -1; |
| 7794 } | 6746 } |
| 7795 | 6747 |
| 7796 return fd; | 6748 return fd; |
| 7797 } | 6749 } |
| 7798 | 6750 |
| 7799 static int | 6751 static int |
| 7800 gdb_ust_socket_init (void) | 6752 gdb_agent_socket_init (void) |
| 7801 { | 6753 { |
| 7802 int result, fd; | 6754 int result, fd; |
| 7803 char name[UNIX_PATH_MAX]; | 6755 char name[UNIX_PATH_MAX]; |
| 7804 | 6756 |
| 7805 result = xsnprintf (name, UNIX_PATH_MAX, "%s/gdb_ust%d", | 6757 result = xsnprintf (name, UNIX_PATH_MAX, "%s/gdb_ust%d", |
| 7806 SOCK_DIR, getpid ()); | 6758 SOCK_DIR, getpid ()); |
| 7807 if (result >= UNIX_PATH_MAX) | 6759 if (result >= UNIX_PATH_MAX) |
| 7808 { | 6760 { |
| 7809 trace_debug ("string overflow allocating socket name"); | 6761 trace_debug ("string overflow allocating socket name"); |
| 7810 return -1; | 6762 return -1; |
| 7811 } | 6763 } |
| 7812 | 6764 |
| 7813 fd = init_named_socket (name); | 6765 fd = init_named_socket (name); |
| 7814 if (fd < 0) | 6766 if (fd < 0) |
| 7815 warning ("Error initializing named socket (%s) for communication with the " | 6767 warning ("Error initializing named socket (%s) for communication with the " |
| 7816 "ust helper thread. Check that directory exists and that it " | 6768 "ust helper thread. Check that directory exists and that it " |
| 7817 "is writable.", name); | 6769 "is writable.", name); |
| 7818 | 6770 |
| 7819 return fd; | 6771 return fd; |
| 7820 } | 6772 } |
| 7821 | 6773 |
| 7822 /* Return an hexstr version of the STR C string, fit for sending to | 6774 #ifdef HAVE_UST |
| 7823 GDB. */ | |
| 7824 | |
| 7825 static char * | |
| 7826 cstr_to_hexstr (const char *str) | |
| 7827 { | |
| 7828 int len = strlen (str); | |
| 7829 char *hexstr = xmalloc (len * 2 + 1); | |
| 7830 convert_int_to_ascii ((gdb_byte *) str, hexstr, len); | |
| 7831 return hexstr; | |
| 7832 } | |
| 7833 | 6775 |
| 7834 /* The next marker to be returned on a qTsSTM command. */ | 6776 /* The next marker to be returned on a qTsSTM command. */ |
| 7835 static const struct marker *next_st; | 6777 static const struct marker *next_st; |
| 7836 | 6778 |
| 7837 /* Returns the first known marker. */ | 6779 /* Returns the first known marker. */ |
| 7838 | 6780 |
| 7839 struct marker * | 6781 struct marker * |
| 7840 first_marker (void) | 6782 first_marker (void) |
| 7841 { | 6783 { |
| 7842 struct marker_iter iter; | 6784 struct marker_iter iter; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 7862 if (iter.marker == m) | 6804 if (iter.marker == m) |
| 7863 { | 6805 { |
| 7864 USTF(marker_iter_next) (&iter); | 6806 USTF(marker_iter_next) (&iter); |
| 7865 return iter.marker; | 6807 return iter.marker; |
| 7866 } | 6808 } |
| 7867 } | 6809 } |
| 7868 | 6810 |
| 7869 return NULL; | 6811 return NULL; |
| 7870 } | 6812 } |
| 7871 | 6813 |
| 6814 /* Return an hexstr version of the STR C string, fit for sending to |
| 6815 GDB. */ |
| 6816 |
| 6817 static char * |
| 6818 cstr_to_hexstr (const char *str) |
| 6819 { |
| 6820 int len = strlen (str); |
| 6821 char *hexstr = xmalloc (len * 2 + 1); |
| 6822 convert_int_to_ascii ((gdb_byte *) str, hexstr, len); |
| 6823 return hexstr; |
| 6824 } |
| 6825 |
| 7872 /* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat | 6826 /* Compose packet that is the response to the qTsSTM/qTfSTM/qTSTMat |
| 7873 packets. */ | 6827 packets. */ |
| 7874 | 6828 |
| 7875 static void | 6829 static void |
| 7876 response_ust_marker (char *packet, const struct marker *st) | 6830 response_ust_marker (char *packet, const struct marker *st) |
| 7877 { | 6831 { |
| 7878 char *strid, *format, *tmp; | 6832 char *strid, *format, *tmp; |
| 7879 | 6833 |
| 7880 next_st = next_marker (st); | 6834 next_st = next_marker (st); |
| 7881 | 6835 |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8022 if ((uintptr_t ) m->location == address) | 6976 if ((uintptr_t ) m->location == address) |
| 8023 { | 6977 { |
| 8024 response_ust_marker (packet, m); | 6978 response_ust_marker (packet, m); |
| 8025 return 0; | 6979 return 0; |
| 8026 } | 6980 } |
| 8027 | 6981 |
| 8028 strcpy (packet, "l"); | 6982 strcpy (packet, "l"); |
| 8029 return -1; | 6983 return -1; |
| 8030 } | 6984 } |
| 8031 | 6985 |
| 6986 static void |
| 6987 gdb_ust_init (void) |
| 6988 { |
| 6989 if (!dlsym_ust ()) |
| 6990 return; |
| 6991 |
| 6992 USTF(ltt_probe_register) (&gdb_ust_probe); |
| 6993 } |
| 6994 |
| 6995 #endif /* HAVE_UST */ |
| 6996 |
| 6997 #include <sys/syscall.h> |
| 6998 |
| 6999 /* Helper thread of agent. */ |
| 7000 |
| 8032 static void * | 7001 static void * |
| 8033 gdb_ust_thread (void *arg) | 7002 gdb_agent_helper_thread (void *arg) |
| 8034 { | 7003 { |
| 8035 int listen_fd; | 7004 int listen_fd; |
| 8036 | 7005 |
| 8037 while (1) | 7006 while (1) |
| 8038 { | 7007 { |
| 8039 listen_fd = gdb_ust_socket_init (); | 7008 listen_fd = gdb_agent_socket_init (); |
| 8040 | 7009 |
| 8041 #ifdef SYS_gettid | |
| 8042 if (helper_thread_id == 0) | 7010 if (helper_thread_id == 0) |
| 8043 helper_thread_id = syscall (SYS_gettid); | 7011 helper_thread_id = syscall (SYS_gettid); |
| 8044 #endif | |
| 8045 | 7012 |
| 8046 if (listen_fd == -1) | 7013 if (listen_fd == -1) |
| 8047 { | 7014 { |
| 8048 warning ("could not create sync socket\n"); | 7015 warning ("could not create sync socket\n"); |
| 8049 break; | 7016 break; |
| 8050 } | 7017 } |
| 8051 | 7018 |
| 8052 while (1) | 7019 while (1) |
| 8053 { | 7020 { |
| 8054 socklen_t tmp; | 7021 socklen_t tmp; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 8081 if (ret == -1) | 7048 if (ret == -1) |
| 8082 { | 7049 { |
| 8083 warning ("reading socket (fd=%d) failed with %s", | 7050 warning ("reading socket (fd=%d) failed with %s", |
| 8084 fd, strerror (errno)); | 7051 fd, strerror (errno)); |
| 8085 close (fd); | 7052 close (fd); |
| 8086 break; | 7053 break; |
| 8087 } | 7054 } |
| 8088 | 7055 |
| 8089 if (cmd_buf[0]) | 7056 if (cmd_buf[0]) |
| 8090 { | 7057 { |
| 7058 #ifdef HAVE_UST |
| 8091 if (strcmp ("qTfSTM", cmd_buf) == 0) | 7059 if (strcmp ("qTfSTM", cmd_buf) == 0) |
| 8092 { | 7060 { |
| 8093 cmd_qtfstm (cmd_buf); | 7061 cmd_qtfstm (cmd_buf); |
| 8094 } | 7062 } |
| 8095 else if (strcmp ("qTsSTM", cmd_buf) == 0) | 7063 else if (strcmp ("qTsSTM", cmd_buf) == 0) |
| 8096 { | 7064 { |
| 8097 cmd_qtsstm (cmd_buf); | 7065 cmd_qtsstm (cmd_buf); |
| 8098 } | 7066 } |
| 8099 else if (strncmp ("unprobe_marker_at:", | 7067 else if (strncmp ("unprobe_marker_at:", |
| 8100 cmd_buf, | 7068 cmd_buf, |
| 8101 sizeof ("unprobe_marker_at:") - 1) == 0) | 7069 sizeof ("unprobe_marker_at:") - 1) == 0) |
| 8102 { | 7070 { |
| 8103 unprobe_marker_at (cmd_buf); | 7071 unprobe_marker_at (cmd_buf); |
| 8104 } | 7072 } |
| 8105 else if (strncmp ("probe_marker_at:", | 7073 else if (strncmp ("probe_marker_at:", |
| 8106 cmd_buf, | 7074 cmd_buf, |
| 8107 sizeof ("probe_marker_at:") - 1) == 0) | 7075 sizeof ("probe_marker_at:") - 1) == 0) |
| 8108 { | 7076 { |
| 8109 probe_marker_at (cmd_buf); | 7077 probe_marker_at (cmd_buf); |
| 8110 } | 7078 } |
| 8111 else if (strncmp ("qTSTMat:", | 7079 else if (strncmp ("qTSTMat:", |
| 8112 cmd_buf, | 7080 cmd_buf, |
| 8113 sizeof ("qTSTMat:") - 1) == 0) | 7081 sizeof ("qTSTMat:") - 1) == 0) |
| 8114 { | 7082 { |
| 8115 cmd_qtstmat (cmd_buf); | 7083 cmd_qtstmat (cmd_buf); |
| 8116 } | 7084 } |
| 8117 » else if (strcmp (cmd_buf, "help") == 0) | 7085 #endif /* HAVE_UST */ |
| 8118 » » { | |
| 8119 » » strcpy (cmd_buf, "for help, press F1\n"); | |
| 8120 » » } | |
| 8121 » else | |
| 8122 » » strcpy (cmd_buf, ""); | |
| 8123 } | 7086 } |
| 8124 | 7087 |
| 8125 » write (fd, buf, 1); | 7088 » /* Fix compiler's warning: ignoring return value of 'write'. */ |
| 7089 » ret = write (fd, buf, 1); |
| 8126 close (fd); | 7090 close (fd); |
| 8127 } | 7091 } |
| 8128 } | 7092 } |
| 8129 | 7093 |
| 8130 return NULL; | 7094 return NULL; |
| 8131 } | 7095 } |
| 8132 | 7096 |
| 8133 #include <signal.h> | 7097 #include <signal.h> |
| 7098 #include <pthread.h> |
| 7099 |
| 7100 IP_AGENT_EXPORT int gdb_agent_capability = AGENT_CAPA_STATIC_TRACE; |
| 8134 | 7101 |
| 8135 static void | 7102 static void |
| 8136 gdb_ust_init (void) | 7103 gdb_agent_init (void) |
| 8137 { | 7104 { |
| 8138 int res; | 7105 int res; |
| 8139 pthread_t thread; | 7106 pthread_t thread; |
| 8140 sigset_t new_mask; | 7107 sigset_t new_mask; |
| 8141 sigset_t orig_mask; | 7108 sigset_t orig_mask; |
| 8142 | 7109 |
| 8143 if (!dlsym_ust ()) | |
| 8144 return; | |
| 8145 | |
| 8146 /* We want the helper thread to be as transparent as possible, so | 7110 /* We want the helper thread to be as transparent as possible, so |
| 8147 have it inherit an all-signals-blocked mask. */ | 7111 have it inherit an all-signals-blocked mask. */ |
| 8148 | 7112 |
| 8149 sigfillset (&new_mask); | 7113 sigfillset (&new_mask); |
| 8150 res = pthread_sigmask (SIG_SETMASK, &new_mask, &orig_mask); | 7114 res = pthread_sigmask (SIG_SETMASK, &new_mask, &orig_mask); |
| 8151 if (res) | 7115 if (res) |
| 8152 fatal ("pthread_sigmask (1) failed: %s", strerror (res)); | 7116 fatal ("pthread_sigmask (1) failed: %s", strerror (res)); |
| 8153 | 7117 |
| 8154 res = pthread_create (&thread, | 7118 res = pthread_create (&thread, |
| 8155 NULL, | 7119 NULL, |
| 8156 » » » gdb_ust_thread, | 7120 » » » gdb_agent_helper_thread, |
| 8157 NULL); | 7121 NULL); |
| 8158 | 7122 |
| 8159 res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL); | 7123 res = pthread_sigmask (SIG_SETMASK, &orig_mask, NULL); |
| 8160 if (res) | 7124 if (res) |
| 8161 fatal ("pthread_sigmask (2) failed: %s", strerror (res)); | 7125 fatal ("pthread_sigmask (2) failed: %s", strerror (res)); |
| 8162 | 7126 |
| 8163 while (helper_thread_id == 0) | 7127 while (helper_thread_id == 0) |
| 8164 usleep (1); | 7128 usleep (1); |
| 8165 | 7129 |
| 8166 USTF(ltt_probe_register) (&gdb_ust_probe); | 7130 #ifdef HAVE_UST |
| 7131 gdb_ust_init (); |
| 7132 #endif |
| 8167 } | 7133 } |
| 8168 | 7134 |
| 8169 #endif /* HAVE_UST */ | |
| 8170 | |
| 8171 #include <sys/mman.h> | 7135 #include <sys/mman.h> |
| 8172 #include <fcntl.h> | 7136 #include <fcntl.h> |
| 8173 | 7137 |
| 8174 IP_AGENT_EXPORT char *gdb_tp_heap_buffer; | 7138 IP_AGENT_EXPORT char *gdb_tp_heap_buffer; |
| 8175 IP_AGENT_EXPORT char *gdb_jump_pad_buffer; | 7139 IP_AGENT_EXPORT char *gdb_jump_pad_buffer; |
| 8176 IP_AGENT_EXPORT char *gdb_jump_pad_buffer_end; | 7140 IP_AGENT_EXPORT char *gdb_jump_pad_buffer_end; |
| 8177 IP_AGENT_EXPORT char *gdb_trampoline_buffer; | 7141 IP_AGENT_EXPORT char *gdb_trampoline_buffer; |
| 8178 IP_AGENT_EXPORT char *gdb_trampoline_buffer_end; | 7142 IP_AGENT_EXPORT char *gdb_trampoline_buffer_end; |
| 8179 IP_AGENT_EXPORT char *gdb_trampoline_buffer_error; | 7143 IP_AGENT_EXPORT char *gdb_trampoline_buffer_error; |
| 8180 | 7144 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 8191 strncpy (gdb_trampoline_buffer_error, errmsg, 99); | 7155 strncpy (gdb_trampoline_buffer_error, errmsg, 99); |
| 8192 else | 7156 else |
| 8193 strcpy (gdb_trampoline_buffer_error, "no buffer passed"); | 7157 strcpy (gdb_trampoline_buffer_error, "no buffer passed"); |
| 8194 } | 7158 } |
| 8195 | 7159 |
| 8196 static void __attribute__ ((constructor)) | 7160 static void __attribute__ ((constructor)) |
| 8197 initialize_tracepoint_ftlib (void) | 7161 initialize_tracepoint_ftlib (void) |
| 8198 { | 7162 { |
| 8199 initialize_tracepoint (); | 7163 initialize_tracepoint (); |
| 8200 | 7164 |
| 8201 #ifdef HAVE_UST | 7165 gdb_agent_init (); |
| 8202 gdb_ust_init (); | |
| 8203 #endif | |
| 8204 } | 7166 } |
| 8205 | 7167 |
| 8206 #endif /* IN_PROCESS_AGENT */ | 7168 #endif /* IN_PROCESS_AGENT */ |
| 8207 | 7169 |
| 8208 /* Return a timestamp, expressed as microseconds of the usual Unix | 7170 /* Return a timestamp, expressed as microseconds of the usual Unix |
| 8209 time. (As the result is a 64-bit number, it will not overflow any | 7171 time. (As the result is a 64-bit number, it will not overflow any |
| 8210 time soon.) */ | 7172 time soon.) */ |
| 8211 | 7173 |
| 8212 static LONGEST | 7174 static LONGEST |
| 8213 get_timestamp (void) | 7175 get_timestamp (void) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 8231 /* Wire trace state variable 1 to be the timestamp. This will be | 7193 /* Wire trace state variable 1 to be the timestamp. This will be |
| 8232 uploaded to GDB upon connection and become one of its trace state | 7194 uploaded to GDB upon connection and become one of its trace state |
| 8233 variables. (In case you're wondering, if GDB already has a trace | 7195 variables. (In case you're wondering, if GDB already has a trace |
| 8234 variable numbered 1, it will be renumbered.) */ | 7196 variable numbered 1, it will be renumbered.) */ |
| 8235 create_trace_state_variable (1, 0); | 7197 create_trace_state_variable (1, 0); |
| 8236 set_trace_state_variable_name (1, "trace_timestamp"); | 7198 set_trace_state_variable_name (1, "trace_timestamp"); |
| 8237 set_trace_state_variable_getter (1, get_timestamp); | 7199 set_trace_state_variable_getter (1, get_timestamp); |
| 8238 | 7200 |
| 8239 #ifdef IN_PROCESS_AGENT | 7201 #ifdef IN_PROCESS_AGENT |
| 8240 { | 7202 { |
| 7203 uintptr_t addr; |
| 8241 int pagesize; | 7204 int pagesize; |
| 7205 |
| 8242 pagesize = sysconf (_SC_PAGE_SIZE); | 7206 pagesize = sysconf (_SC_PAGE_SIZE); |
| 8243 if (pagesize == -1) | 7207 if (pagesize == -1) |
| 8244 fatal ("sysconf"); | 7208 fatal ("sysconf"); |
| 8245 | 7209 |
| 8246 gdb_tp_heap_buffer = xmalloc (5 * 1024 * 1024); | 7210 gdb_tp_heap_buffer = xmalloc (5 * 1024 * 1024); |
| 8247 | 7211 |
| 8248 /* Allocate scratch buffer aligned on a page boundary. */ | 7212 #define SCRATCH_BUFFER_NPAGES 20 |
| 8249 gdb_jump_pad_buffer = memalign (pagesize, pagesize * 20); | |
| 8250 gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + pagesize * 20; | |
| 8251 | 7213 |
| 8252 /* Make it writable and executable. */ | 7214 /* Allocate scratch buffer aligned on a page boundary, at a low |
| 8253 if (mprotect (gdb_jump_pad_buffer, pagesize * 20, | 7215 address (close to the main executable's code). */ |
| 8254 » » PROT_READ | PROT_WRITE | PROT_EXEC) != 0) | 7216 for (addr = pagesize; addr != 0; addr += pagesize) |
| 7217 { |
| 7218 » gdb_jump_pad_buffer = mmap ((void *) addr, pagesize * SCRATCH_BUFFER_NPA
GES, |
| 7219 » » » » PROT_READ | PROT_WRITE | PROT_EXEC, |
| 7220 » » » » MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, |
| 7221 » » » » -1, 0); |
| 7222 » if (gdb_jump_pad_buffer != MAP_FAILED) |
| 7223 » break; |
| 7224 } |
| 7225 |
| 7226 if (addr == 0) |
| 8255 fatal ("\ | 7227 fatal ("\ |
| 8256 initialize_tracepoint: mprotect(%p, %d, PROT_READ|PROT_EXEC) failed with %s", | 7228 initialize_tracepoint: mmap'ing jump pad buffer failed with %s", |
| 8257 » gdb_jump_pad_buffer, pagesize * 20, strerror (errno)); | 7229 » strerror (errno)); |
| 7230 |
| 7231 gdb_jump_pad_buffer_end = gdb_jump_pad_buffer + pagesize * SCRATCH_BUFFER_NP
AGES; |
| 8258 } | 7232 } |
| 8259 | 7233 |
| 8260 gdb_trampoline_buffer = gdb_trampoline_buffer_end = 0; | 7234 gdb_trampoline_buffer = gdb_trampoline_buffer_end = 0; |
| 8261 | 7235 |
| 8262 /* It's not a fatal error for something to go wrong with trampoline | 7236 /* It's not a fatal error for something to go wrong with trampoline |
| 8263 buffer setup, but it can be mysterious, so create a channel to | 7237 buffer setup, but it can be mysterious, so create a channel to |
| 8264 report back on what went wrong, using a fixed size since we may | 7238 report back on what went wrong, using a fixed size since we may |
| 8265 not be able to allocate space later when the problem occurs. */ | 7239 not be able to allocate space later when the problem occurs. */ |
| 8266 gdb_trampoline_buffer_error = xmalloc (IPA_BUFSIZ); | 7240 gdb_trampoline_buffer_error = xmalloc (IPA_BUFSIZ); |
| 8267 | 7241 |
| 8268 strcpy (gdb_trampoline_buffer_error, "No errors reported"); | 7242 strcpy (gdb_trampoline_buffer_error, "No errors reported"); |
| 8269 | 7243 |
| 8270 initialize_low_tracepoint (); | 7244 initialize_low_tracepoint (); |
| 8271 #endif | 7245 #endif |
| 8272 } | 7246 } |
| OLD | NEW |