home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-27 | 31.7 KB | 1,049 lines |
- Newsgroups: gnu.gdb.bug
- Path: sparky!uunet!cis.ohio-state.edu!mermaid.micro.umn.edu!daney
- From: daney@mermaid.micro.umn.edu (Dave Daney)
- Subject: Debug register use for ISC 2.2.1 (Sys v/386 R3.2)
- Message-ID: <199207271614.AA07753@mermaid.micro.umn.edu>
- Sender: gnulists@ai.mit.edu
- Organization: GNUs Not Usenet
- Distribution: gnu
- Date: Mon, 27 Jul 1992 06:14:50 GMT
- Approved: bug-gdb@prep.ai.mit.edu
- Lines: 1036
-
- I have had several requests for my patches for debug register use for
- Interactive 2.2.1 so I am posting the slightly modified for gdb-4.6 version.
-
- I think someone told me they work on SCO also but I have not ever seen it
- so I make no claims to that, actually I probably shouldn't claim it works
- on anything.
-
- I have made a few modifications to gdb-4.6 to use the hardware debug
- registers on the 386 running Interactive 2.2.1 (Sys V/386 Rel3.2).
-
- They are implemented as a new type of breakpoint(I called it an Accesspoint).
- I thought that they should be seperate from watchpoints because watchpoints break
- on a whole expression changing. Which is different than a breakpoint on a memory
- access, they (watchpoints) probably are usefull even with accesspoints. Any how
- there are two new commands to implement Accesspoints.
-
- wbreak: Break on a memory write to a location.
- abreak: Break on a memory access (read or write) to a location.
-
- They can be set on any expression that evaluates to some thing located in a
- memory location.
-
- Special note: To set an access breakpoint on location 0 (good for catching
- reads or writes from a NULL pointer).
-
- abreak *(int *)0
-
- All of the rest of the breakpoint commands work on Accesspoints (info, enable,
- disable, delete, ... . I haven't had any problems with them, although I have only
- had this going on gdb-4.6 for a couple of days. However I have been using this
- with gdb-4.5 ever since it came out.
-
- I think It is fairly straight forward. I didn't make any info files for this.
-
-
- I put the machine dependant parts in i386-xdep.c most of the rest of it is
- in breakpoint.c. Several other files just had the
- struct target_ops XXXXX_target structures modified.
-
- I think(hope) that all of the changes are inside of
- #ifdef HAVE_MEM_BEEAKPOINT
- #endif
- blocks so hopefully this will not break any thing if you don't define
- -DHAVE_MEM_BREAKPOINT
- not positive about this however. I hope this addition fits into the
- scheme of gdb and does not break things for other systems. Let me know.
-
-
- On the 386 there are only four Access breakpoint registers, they can be set
- for one, two, and four byte accesses. The addresses must be properly aligned.
- The code in i386-xdep.c takes all of this into account, it will use as many
- registers as necessary to cover the requested area. If the registers are
- exausted it will disable the Accesspoint. There is a bug(feature) here, if
- multiple registers are needed and at least one is available it will fill from
- the bottom of the area requested. Then it will report no more registers and disable
- the Access point. It does not deallocate the registers from the failed attempt.
- When execution is resumed (continue) the access point is still set on the first
- portion of the area. If it is hit you will get some message about a SIGTRAP, but
- the Accesspoint information will not print. In short, set Accesspoints on
- small properly aligned objects.
-
-
-
- I configured like this:
-
- configure i386-none-sysv32
-
- Here is how I made it. The trad-core things are to get corefiles to read on this
- machine, but trad-core.c needs to be patched for it to work (see other posting).
- For other 386 systems perhaps just -DHAVE_MEM_BREAKPOINT is sufficient.
- I have a feeling that the things in i386-xdep.c might be different for other
- systems.
-
- gmake CC=gcc HDEFINES="-D_POSIX_SOURCE -DTRAD_CORE" HDEPFILES=trad-core.o\
- READLINE_DEFINES="-D_POSIX_VERSION -D_POSIX_SOURCE" LOADLIBES=-lcposix\
- USER_CFLAGS=-DHAVE_MEM_BREAKPOINT CFLAGS="-g -O2"
-
-
-
-
- *** breakpoint.c Mon Jul 6 12:10:37 1992
- --- ../../gdb-4.6.new/gdb/breakpoint.c Fri Jul 24 16:14:04 1992
- ***************
- *** 133,139 ****
- --- 133,152 ----
- static void
- set_breakpoint_count PARAMS ((int));
-
- + #ifdef HAVE_MEM_BREAKPOINT
-
- + static void
- + write_access_breakpoint_command PARAMS ((char *, int));
- +
- + static void
- + rw_access_breakpoint_command PARAMS ((char *, int));
- +
- + static void
- + access_breakpoint_command PARAMS ((char *, int, enum access_break_type));
- +
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- +
- extern int addressprint; /* Print machine addresses? */
- extern int demangle; /* Print de-mangled symbol names? */
-
- ***************
- *** 433,438 ****
- --- 446,454 ----
-
- ALL_BREAKPOINTS (b)
- if (b->type != bp_watchpoint
- + #ifdef HAVE_MEM_BREAKPOINT
- + && b->type != bp_accesspoint
- + #endif
- && b->enable != disabled
- && ! b->inserted
- && ! b->duplicate)
- ***************
- *** 449,455 ****
- if (!disabled_breaks)
- {
- fprintf (stderr,
- ! "Cannot insert breakpoint %d:\n", b->number);
- printf_filtered ("Disabling shared library breakpoints:\n");
- }
- disabled_breaks = 1;
- --- 465,471 ----
- if (!disabled_breaks)
- {
- fprintf (stderr,
- ! "Cannot insert breakpoint %d:\n", b->number);
- printf_filtered ("Disabling shared library breakpoints:\n");
- }
- disabled_breaks = 1;
- ***************
- *** 461,467 ****
- fprintf (stderr, "Cannot insert breakpoint %d:\n", b->number);
- #ifdef ONE_PROCESS_WRITETEXT
- fprintf (stderr,
- ! "The same program may be running in another process.\n");
- #endif
- memory_error (val, b->address); /* which bombs us out */
- }
- --- 477,483 ----
- fprintf (stderr, "Cannot insert breakpoint %d:\n", b->number);
- #ifdef ONE_PROCESS_WRITETEXT
- fprintf (stderr,
- ! "The same program may be running in another process.\n");
- #endif
- memory_error (val, b->address); /* which bombs us out */
- }
- ***************
- *** 471,476 ****
- --- 487,513 ----
- }
- if (disabled_breaks)
- printf_filtered ("\n");
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- + target_init_access_breakpoint();
- +
- + ALL_BREAKPOINTS (b)
- + if (b->type == bp_accesspoint && b->enable != disabled)
- + {
- + int rv;
- + rv = target_insert_access_breakpoint(b->access_break_address,
- + b->access_break_length,
- + b->access_break_type, b->number);
- + if (rv)
- + {
- + /* Can't set the breakpoint. */
- + fprintf(stderr, "Cannot set memory breakpoint %d. Disableing it.\n", b->number);
- + fprintf(stderr, "It is best to set memory breakpoints on small properly\n");
- + fprintf(stderr, "aligned objects\n");
- + b->enable = disabled;
- + }
- + }
- + #endif /* HAVE_MEM_BREAKPOINT */
- return val;
- }
-
- ***************
- *** 500,505 ****
- --- 537,545 ----
- local_hex_string(b->shadow_contents[1]));
- #endif /* BREAKPOINT_DEBUG */
- }
- + #ifdef HAVE_MEM_BREAKPOINT
- + target_init_access_breakpoint();
- + #endif /* HAVE_MEM_BREAKPOINT */
-
- return 0;
- }
- ***************
- *** 707,712 ****
- --- 747,755 ----
- if (bs == NULL
- || bs->breakpoint_at == NULL
- || (bs->breakpoint_at->type != bp_breakpoint
- + #ifdef HAVE_MEM_BREAKPOINT
- + && bs->breakpoint_at->type != bp_accesspoint
- + #endif /* HAVE_MEM_BREAKPOINT */
- && bs->breakpoint_at->type != bp_watchpoint))
- return 0;
-
- ***************
- *** 742,748 ****
- bs->old_val = NULL;
- return 1;
- }
- !
- /* Maybe another breakpoint in the chain caused us to stop.
- (Currently all watchpoints go on the bpstat whether hit or
- not. That probably could (should) be changed, provided care is taken
- --- 785,808 ----
- bs->old_val = NULL;
- return 1;
- }
- ! #ifdef HAVE_MEM_BREAKPOINT
- ! if (bs->breakpoint_at->type == bp_accesspoint)
- ! {
- ! printf_filtered ("\nMemory access breakpoint %d, ", bs->breakpoint_at->number);
- ! printf_filtered ("%-10s",
- ! local_hex_string(bs->breakpoint_at->access_break_address));
- ! printf_filtered (" ");
- ! if(bs->breakpoint_at->access_break_type == access_break_write)
- ! printf_filtered ("w ");
- ! else
- ! printf_filtered ("r/w");
- ! printf_filtered (" ");
- ! printf_filtered ("%d ", bs->breakpoint_at->access_break_length);
- ! print_expression (bs->breakpoint_at->access_break_exp, stdout);
- ! printf_filtered ("\n");
- ! return 0;
- ! }
- ! #endif /* HAVE_MEM_BREAKPOINT */
- /* Maybe another breakpoint in the chain caused us to stop.
- (Currently all watchpoints go on the bpstat whether hit or
- not. That probably could (should) be changed, provided care is taken
- ***************
- *** 817,822 ****
- --- 877,885 ----
- /* True if we've hit a breakpoint (as opposed to a watchpoint). */
- int real_breakpoint = 0;
- #endif
- + #ifdef HAVE_MEM_BREAKPOINT
- + int access_breakpoint = target_get_access_breakpoint_status();
- + #endif
- /* Root of the chain of bpstat's */
- struct bpstat root_bs[1];
- /* Pointer to the last thing in the chain currently. */
- ***************
- *** 833,841 ****
- if (b->enable == disabled)
- continue;
-
- ! if (b->type != bp_watchpoint && b->address != bp_addr)
- continue;
-
- /* Come here if it's a watchpoint, or if the break address matches */
-
- bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
- --- 896,912 ----
- if (b->enable == disabled)
- continue;
-
- ! #ifdef HAVE_MEM_BREAKPOINT
- ! if (b->type != bp_watchpoint && b->address != bp_addr &&
- ! b->type != bp_accesspoint)
- continue;
-
- + if(b->type == bp_accesspoint && b->number != access_breakpoint)
- + continue;
- + #else
- + if (b->type != bp_watchpoint && b->address != bp_addr)
- + continue;
- + #endif /* HAVE_MEM_BREAKPOINT */
- /* Come here if it's a watchpoint, or if the break address matches */
-
- bs = bpstat_alloc (b, bs); /* Alloc a bpstat to explain stop */
- ***************
- *** 896,903 ****
- --- 967,979 ----
- }
- }
- #if DECR_PC_AFTER_BREAK != 0 || defined (SHIFT_INST_REGS)
- + #ifdef HAVE_MEM_BREAKPOINT
- + else if (b->type != bp_accesspoint)
- + real_breakpoint = 1;
- + #else
- else
- real_breakpoint = 1;
- + #endif /* HAVE_MEM_BREAKPOINT */
- #endif
-
- if (b->frame && b->frame != frame_address)
- ***************
- *** 990,998 ****
- return 0;
- }
-
- ! /* Print information on breakpoint number BNUM, or -1 if all.
- ! If WATCHPOINTS is zero, process only breakpoints; if WATCHPOINTS
- ! is nonzero, process only watchpoints. */
-
- static void
- breakpoint_1 (bnum, allflag)
- --- 1066,1072 ----
- return 0;
- }
-
- ! /* Print information on breakpoint number BNUM, or -1 if all. */
-
- static void
- breakpoint_1 (bnum, allflag)
- ***************
- *** 1005,1011 ****
- CORE_ADDR last_addr = (CORE_ADDR)-1;
- int found_a_breakpoint = 0;
- static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
- ! "longjmp", "longjmp resume"};
- static char *bpdisps[] = {"del", "dis", "keep"};
- static char bpenables[] = "ny";
-
- --- 1079,1090 ----
- CORE_ADDR last_addr = (CORE_ADDR)-1;
- int found_a_breakpoint = 0;
- static char *bptypes[] = {"breakpoint", "until", "finish", "watchpoint",
- ! "longjmp", "longjmp resume"
- ! #ifdef HAVE_MEM_BREAKPOINT
- ! ,"accesspoint"
- ! #endif /* HAVE_MEM_BREAKPOINT */
- ! };
- !
- static char *bpdisps[] = {"del", "dis", "keep"};
- static char bpenables[] = "ny";
-
- ***************
- *** 1022,1028 ****
- /* We only print out user settable breakpoints unless the allflag is set. */
- if (!allflag
- && b->type != bp_breakpoint
- ! && b->type != bp_watchpoint)
- continue;
-
- if (!found_a_breakpoint++)
- --- 1101,1111 ----
- /* We only print out user settable breakpoints unless the allflag is set. */
- if (!allflag
- && b->type != bp_breakpoint
- ! && b->type != bp_watchpoint
- ! #ifdef HAVE_MEM_BREAKPOINT
- ! && b->type != bp_accesspoint
- ! #endif /* HAVE_MEM_BREAKPOINT */
- ! )
- continue;
-
- if (!found_a_breakpoint++)
- ***************
- *** 1039,1044 ****
- --- 1122,1141 ----
- case bp_watchpoint:
- print_expression (b->exp, stdout);
- break;
- + #ifdef HAVE_MEM_BREAKPOINT
- + case bp_accesspoint:
- + if (addressprint)
- + printf_filtered ("%s ",
- + local_hex_string_custom(b->access_break_address,
- + "08"));
- + if(b->access_break_type == access_break_write)
- + printf_filtered ("(w ");
- + else
- + printf_filtered ("(r/w ");
- + printf_filtered ("%d) ", b->access_break_length);
- + print_expression (b->access_break_exp, stdout);
- + break;
- + #endif /* HAVE_MEM_BREAKPOINT */
- case bp_breakpoint:
- case bp_until:
- case bp_finish:
- ***************
- *** 1185,1191 ****
- register struct breakpoint *b;
- register int count = 0;
-
- ! if (address == 0) /* Watchpoints are uninteresting */
- return;
-
- ALL_BREAKPOINTS (b)
- --- 1282,1288 ----
- register struct breakpoint *b;
- register int count = 0;
-
- ! if (address == 0) /* Watchpoints and access_breakpoints are uninteresting */
- return;
-
- ALL_BREAKPOINTS (b)
- ***************
- *** 1371,1376 ****
- --- 1468,1479 ----
- {
- switch (b->type)
- {
- + #ifdef HAVE_MEM_BREAKPOINT
- + case bp_accesspoint:
- + printf_filtered ("Memory accesspoint %d at %s", b->number,
- + local_hex_string_custom(b->access_break_address, "08"));
- + break;
- + #endif /* HAVE_MEM_BREAKPOINT */
- case bp_watchpoint:
- printf_filtered ("Watchpoint %d: ", b->number);
- print_expression (b->exp, stdout);
- ***************
- *** 1622,1627 ****
- --- 1725,1792 ----
- b->cond_string = NULL;
- mention (b);
- }
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- + /* ARGSUSED */
- + static void
- + access_breakpoint_command (arg, from_tty, mode)
- + char *arg;
- + int from_tty;
- + enum access_break_type mode;
- + {
- + struct breakpoint *b;
- + struct symtab_and_line sal;
- + struct expression *exp;
- + struct block *exp_valid_block;
- + struct value *access_obj;
- +
- + sal.pc = 0;
- + sal.symtab = NULL;
- + sal.line = 0;
- +
- + /* Parse arguments. */
- + innermost_block = NULL;
- + exp = parse_expression (arg);
- + exp_valid_block = innermost_block;
- + access_obj = evaluate_expression (exp);
- +
- + if(lval_memory != VALUE_LVAL(access_obj))
- + error("requested access breakpoint not in memory. e.g. register or constant.");
- +
- + /* Now set up the breakpoint. */
- + b = set_raw_breakpoint (sal);
- + set_breakpoint_count (breakpoint_count + 1);
- + b->number = breakpoint_count;
- + b->type = bp_accesspoint;
- + b->disposition = donttouch;
- + b->exp = 0;
- + b->exp_valid_block = NULL;
- + b->val = NULL;
- + b->cond = 0;
- + b->cond_string = NULL;
- + b->access_break_exp = exp;
- + b->access_break_address = VALUE_ADDRESS(access_obj) + VALUE_OFFSET(access_obj);
- + b->access_break_length = TYPE_LENGTH(VALUE_TYPE(access_obj));
- + b->access_break_type = mode;
- + mention (b);
- + }
- + static void
- + write_access_breakpoint_command (arg, from_tty)
- + char *arg;
- + int from_tty;
- + {
- + access_breakpoint_command (arg, from_tty, access_break_write);
- + }
- + static void
- + rw_access_breakpoint_command (arg, from_tty)
- + char *arg;
- + int from_tty;
- + {
- + access_breakpoint_command (arg, from_tty, access_break_rw);
- + }
- +
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
-
- /*
- * Helper routine for the until_command routine in infcmd.c. Here
- ***************
- *** 2063,2068 ****
- --- 2228,2236 ----
- ALL_BREAKPOINTS (b)
- while (b->next
- && b->next->type != bp_watchpoint
- + #ifdef HAVE_MEM_BREAKPOINT
- + && b->next->type != bp_accesspoint
- + #endif /* HAVE_MEM_BREAKPOINT */
- && (sal.pc ? b->next->address == sal.pc
- : (b->next->symtab == sal.symtab
- && b->next->line_number == sal.line)))
- ***************
- *** 2232,2237 ****
- --- 2400,2408 ----
- break;
- default:
- printf_filtered ("Deleting unknown breakpoint type %d\n", b->type);
- + #ifdef HAVE_MEM_BREAKPOINT
- + case bp_accesspoint:
- + #endif /*HAVE_MEM_BREAKPOINT */
- case bp_until:
- case bp_finish:
- case bp_longjmp:
- ***************
- *** 2615,2620 ****
- --- 2786,2802 ----
- This command may be abbreviated \"delete\".",
- &deletelist);
-
- + #ifdef HAVE_MEM_BREAKPOINT
- + add_com ("wbreak", class_breakpoint, write_access_breakpoint_command,
- + "Set a memory write breakpoint at a location.\n\
- + A memory write breakpoint stops execution of your program whenever it\n\
- + tries to write data at that location.");
- +
- + add_com ("abreak", class_breakpoint, rw_access_breakpoint_command,
- + "Set a memory acsess breakpoint at a location.\n\
- + A memory acsess breakpoint stops execution of your program whenever it\n\
- + tries to read or write data at that location.");
- + #endif /* HAVE_MEM_BREAKPOINT */
- add_com ("clear", class_breakpoint, clear_command,
- "Clear breakpoint at specified line or function.\n\
- Argument may be line number, function name, or \"*\" and an address.\n\
- ***************
- *** 2643,2648 ****
- --- 2825,2850 ----
- add_com_alias ("bre", "break", class_run, 1);
- add_com_alias ("brea", "break", class_run, 1);
-
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- +
- + #else /* !HAVE_MEM_BREAKPOINT */
- + add_info ("breakpoints", breakpoints_info,
- + "Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
- + The \"Type\" column indicates one of:\n\
- + \tbreakpoint - normal breakpoint\n\
- + \taccesspoint - memory access breakpoint\n\
- + \twatchpoint - watchpoint\n\
- + The \"Disp\" column contains one of \"keep\", \"del\", or \"dis\" to indicate\n\
- + the disposition of the breakpoint after it gets hit. \"dis\" means that the\n\
- + breakpoint will be disabled. The \"Address\" and \"What\" columns indicate the\n\
- + address and file/line number respectively.\n\n\
- + Convenience variable \"$_\" and default examine address for \"x\"\n\
- + are set to the address of the last breakpoint listed.\n\n\
- + Convenience variable \"$bpnum\" contains the number of the last\n\
- + breakpoint set.");
- +
- + #endif /* !HAVE_MEM_BREAKPOINT */
- add_info ("breakpoints", breakpoints_info,
- "Status of user-settable breakpoints, or breakpoint number NUMBER.\n\
- The \"Type\" column indicates one of:\n\
- *** core.c Mon Jul 6 12:10:41 1992
- --- ../../gdb-4.6.new/gdb/core.c Fri Jul 24 15:32:52 1992
- ***************
- *** 444,449 ****
- --- 444,452 ----
- core_stratum, 0, /* next */
- 0, 1, 1, 1, 0, /* all mem, mem, stack, regs, exec */
- 0, 0, /* section pointers */
- + #ifdef HAVE_MEM_BREAKPOINT
- + 0, 0, 0, 0, /* init, insert, get, clear */
- + #endif
- OPS_MAGIC, /* Always the last thing */
- };
-
- *** exec.c Tue May 12 20:11:42 1992
- --- ../../gdb-4.6.new/gdb/exec.c Fri Jul 24 15:32:53 1992
- ***************
- *** 421,426 ****
- --- 421,429 ----
- file_stratum, 0, /* next */
- 0, 1, 0, 0, 0, /* all mem, mem, stack, regs, exec */
- 0, 0, /* section pointers */
- + #ifdef HAVE_MEM_BREAKPOINT
- + 0, 0, 0, 0, /* init, insert, get, clear */
- + #endif
- OPS_MAGIC, /* Always the last thing */
- };
-
- *** i386-xdep.c Wed Jun 24 12:32:49 1992
- --- ../../gdb-4.6.new/gdb/i386-xdep.c Fri Jul 24 17:05:15 1992
- ***************
- *** 31,36 ****
- --- 31,41 ----
- #include <sys/dir.h>
- #include <signal.h>
- #include <sys/user.h>
- + #ifdef HAVE_MEM_BREAKPOINT
- + #include "breakpoint.h"
- + #include <sys/debugreg.h>
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- #include <sys/ioctl.h>
- #include <fcntl.h>
-
- ***************
- *** 44,49 ****
- --- 49,194 ----
-
- extern struct ext_format ext_format_i387;
-
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- + struct user u;
- + #define u_offset(a, b) ((int)((char *)(&(a.b))-(char *)(&a)))
- +
- + static int free_debug_register;
- + static int debug_control_mirror;
- + /* record here which breakpoint associates with which register */
- + static int breakpoint_lookup[DR_LASTADDR + 1];
- +
- + void clear_access_breakpoint_status()
- + {
- + call_ptrace(6, inferior_pid, u_offset(u, u_debugreg[DR_STATUS]), 0);
- + }
- +
- + int get_access_breakpoint_status()
- + {
- + int i;
- + int status;
- +
- + status = call_ptrace(3, inferior_pid, u_offset(u, u_debugreg[DR_STATUS]), 0);
- +
- + for(i = 0; i <= DR_LASTADDR; i++)
- + {
- + if(status & (1 << i))
- + return(breakpoint_lookup[i]);
- + }
- + return 0;
- + }
- +
- + void init_access_breakpoint()
- + {
- + int i;
- + /* Clear the status register so only new status info is shown.
- + Turn off debugging by clearing control register */
- + call_ptrace(6, inferior_pid, u_offset(u, u_debugreg[DR_STATUS]), 0);
- + call_ptrace(6, inferior_pid, u_offset(u, u_debugreg[DR_CONTROL]), 0);
- + debug_control_mirror = 0;
- + free_debug_register = DR_FIRSTADDR;
- + for(i = 0; i <= DR_LASTADDR; i++)
- + breakpoint_lookup[i] = 0;
- + }
- +
- + static int size_try_array[16] = {
- + 1, 1, 1, 1, /* trying size one */
- + 2, 1, 2, 1, /* trying size two */
- + 2, 1, 2, 1, /* trying size three */
- + 4, 1, 2, 1 /* trying size four */
- + };
- +
- + static int insert_nonaligned_access_breakpoint(addr, length, mode, breakpoint)
- + CORE_ADDR addr;
- + int length;
- + enum access_break_type mode;
- + int breakpoint;
- + {
- + int align;
- + int size;
- + int rv;
- +
- + rv = 0;
- + while(length > 0)
- + {
- + align = addr % 4;
- + size = (length > 4) ? 3 : length - 1; /*four is the maximum length for 386*/
- + size = size_try_array[size * 4 + align];
- +
- + if(rv = insert_access_breakpoint(addr, size, mode, breakpoint))
- + return rv;
- + addr += size;
- + length -= size;
- + }
- + return rv;
- + }
- +
- +
- +
- + int insert_access_breakpoint(addr, length, mode, breakpoint)
- + CORE_ADDR addr;
- + int length;
- + enum access_break_type mode;
- + int breakpoint;
- + {
- + int rv;
- + int read_write_bits, len_bits;
- +
- + if(access_break_write == mode)
- + read_write_bits = DR_RW_WRITE;
- + else if(access_break_rw == mode)
- + read_write_bits = DR_RW_READ;
- + else
- + return 1; /* bad mode! */
- +
- + if(free_debug_register > DR_LASTADDR)
- + return 1; /* no more debug registers! */
- +
- + if(1 == length)
- + {
- + len_bits = DR_LEN_1;
- + }
- + else if(2 == length)
- + {
- + if(addr % 2)
- + return(insert_nonaligned_access_breakpoint(addr, length, mode,
- + breakpoint));
- + len_bits = DR_LEN_2;
- + }
- +
- + else if(4 == length)
- + {
- + if(addr % 4)
- + return(insert_nonaligned_access_breakpoint(addr, length, mode,
- + breakpoint));
- + len_bits = DR_LEN_4;
- + }
- + else
- + {
- + return(insert_nonaligned_access_breakpoint(addr, length, mode,
- + breakpoint));
- + }
- +
- + debug_control_mirror |= ((read_write_bits | len_bits) <<
- + (DR_CONTROL_SHIFT + DR_CONTROL_SIZE * free_debug_register));
- + debug_control_mirror |= (1 << (DR_LOCAL_ENABLE_SHIFT +
- + DR_ENABLE_SIZE * free_debug_register));
- + debug_control_mirror |= DR_LOCAL_SLOWDOWN;
- + debug_control_mirror &= ~DR_CONTROL_RESERVED;
- +
- + call_ptrace(6, inferior_pid,
- + u_offset(u, u_debugreg[DR_CONTROL]), debug_control_mirror);
- + call_ptrace(6, inferior_pid, u_offset(u, u_debugreg[free_debug_register]), addr);
- + /* record where we came from */
- + breakpoint_lookup[free_debug_register] = breakpoint;
- + free_debug_register++;
- + return 0;
- + }
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- +
- +
- /* this table must line up with REGISTER_NAMES in m-i386.h */
- /* symbols like 'EAX' come from <sys/reg.h> */
- static int regmap[] =
- ***************
- *** 194,200 ****
- unsigned int mask;
-
- rounded_addr = uaddr & -sizeof (int);
- ! data = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) rounded_addr, 0);
- mask = 0xff << ((uaddr - rounded_addr) * 8);
-
- fpvalid = ((data & mask) != 0);
- --- 339,345 ----
- unsigned int mask;
-
- rounded_addr = uaddr & -sizeof (int);
- ! data = call_ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) rounded_addr, 0);
- mask = 0xff << ((uaddr - rounded_addr) * 8);
-
- fpvalid = ((data & mask) != 0);
- ***************
- *** 229,235 ****
- ip = (int *)buf;
- for (i = 0; i < rounded_size; i++)
- {
- ! *ip++ = ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) rounded_addr, 0);
- rounded_addr += sizeof (int);
- }
- }
- --- 374,380 ----
- ip = (int *)buf;
- for (i = 0; i < rounded_size; i++)
- {
- ! *ip++ = call_ptrace (3, inferior_pid, (PTRACE_ARG3_TYPE) rounded_addr, 0);
- rounded_addr += sizeof (int);
- }
- }
- *** infrun.c Mon Jul 6 12:10:54 1992
- --- ../../gdb-4.6.new/gdb/infrun.c Fri Jul 24 15:32:54 1992
- ***************
- *** 327,332 ****
- --- 327,336 ----
- DO_DEFERRED_STORES;
- #endif
-
- + #ifdef HAVE_MEM_BREAKPOINT
- + target_clear_access_breakpoint_status();
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- target_resume (step, sig);
- discard_cleanups (old_cleanups);
- }
- ***************
- *** 1079,1084 ****
- --- 1083,1091 ----
- default:
- fprintf(stderr, "Unknown breakpoint type %d\n",
- stop_bpstat->breakpoint_at->type);
- + #ifdef HAVE_MEM_BREAKPOINT
- + case bp_accesspoint:
- + #endif /* HAVE_MEM_BREAKPOINT */
- case bp_watchpoint:
- case bp_breakpoint:
- case bp_until:
- *** inftarg.c Sun Mar 29 17:21:27 1992
- --- ../../gdb-4.6.new/gdb/inftarg.c Fri Jul 24 15:32:55 1992
- ***************
- *** 42,47 ****
- --- 42,56 ----
- static void
- child_detach PARAMS ((char *, int));
-
- + #ifdef HAVE_MEM_BREAKPOINT
- + extern void init_memory_breakpoint();
- + extern int insert_memory_breakpoint();
- + extern int get_memory_breakpoint_status();
- + extern void clear_memory_breakpoint_status();
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- +
- +
- /* Forward declaration */
- extern struct target_ops child_ops;
-
- ***************
- *** 208,213 ****
- --- 217,228 ----
- 1, /* to_has_execution */
- 0, /* sections */
- 0, /* sections_end */
- + #ifdef HAVE_MEM_BREAKPOINT
- + init_access_breakpoint, /* init, insert, get, clear */
- + insert_access_breakpoint,
- + get_access_breakpoint_status,
- + clear_access_breakpoint_status,
- + #endif
- OPS_MAGIC /* to_magic */
- };
-
- *** remote.c Mon Jul 6 12:11:04 1992
- --- ../../gdb-4.6.new/gdb/remote.c Fri Jul 24 15:32:55 1992
- ***************
- *** 1048,1053 ****
- --- 1048,1059 ----
- 1, /* to_has_execution */
- NULL, /* sections */
- NULL, /* sections_end */
- + #ifdef HAVE_MEM_BREAKPOINT
- + NULL, /* accesspoint init */
- + NULL, /* accesspoint insert */
- + NULL, /* accesspoint get */
- + NULL, /* accesspoint clear */
- + #endif
- OPS_MAGIC /* to_magic */
- };
-
- *** target.c Mon Jul 6 12:11:14 1992
- --- ../../gdb-4.6.new/gdb/target.c Fri Jul 24 15:32:56 1992
- ***************
- *** 88,93 ****
- --- 88,96 ----
- dummy_stratum, 0, /* stratum, next */
- 0, 0, 0, 0, 0, /* all mem, mem, stack, regs, exec */
- 0, 0, /* section pointers */
- + #ifdef HAVE_MEM_BREAKPOINT
- + 0, 0, 0, 0, /* init, insert, get, clear */
- + #endif
- OPS_MAGIC,
- };
-
- ***************
- *** 331,337 ****
- de_fault (to_has_stack, 0);
- de_fault (to_has_registers, 0);
- de_fault (to_has_execution, 0);
- !
- #undef de_fault
- }
-
- --- 334,345 ----
- de_fault (to_has_stack, 0);
- de_fault (to_has_registers, 0);
- de_fault (to_has_execution, 0);
- ! #ifdef HAVE_MEM_BREAKPOINT
- ! de_fault (to_init_access_breakpoint, init_access_breakpoint);
- ! de_fault (to_insert_access_breakpoint, insert_access_breakpoint);
- ! de_fault (to_get_access_breakpoint_status, get_access_breakpoint_status);
- ! de_fault (to_clear_access_breakpoint_status, clear_access_breakpoint_status);
- ! #endif /* HAVE_MEM_BREAKPOINT */
- #undef de_fault
- }
-
- *** breakpoint.h Wed Apr 1 13:46:00 1992
- --- ../../gdb-4.6.new/gdb/breakpoint.h Fri Jul 24 15:32:52 1992
- ***************
- *** 23,28 ****
- --- 23,29 ----
- #include "frame.h"
- #include "value.h"
-
- +
- /* This is the maximum number of bytes a breakpoint instruction can take.
- Feel free to increase it. It's just used in a few places to size
- arrays that should be independent of the target architecture. */
- ***************
- *** 130,135 ****
- --- 131,139 ----
- bp_watchpoint, /* Watchpoint */
- bp_longjmp, /* secret breakpoint to find longjmp() */
- bp_longjmp_resume /* secret breakpoint to escape longjmp() */
- + #ifdef HAVE_MEM_BREAKPOINT
- + ,bp_accesspoint /* Memory access breakpoint */
- + #endif /* HAVE_MEM_BREAKPOINT */
- };
-
- /* States of enablement of breakpoint. */
- ***************
- *** 144,149 ****
- --- 148,157 ----
- donttouch /* Leave it alone */
- };
-
- + #ifdef HAVE_MEM_BREAKPOINT
- + enum access_break_type {access_break_write, access_break_rw};
- + #endif /* HAVE_MEM_BREAKPOINT */
- +
- /* Note that the ->silent field is not currently used by any commands
- (though the code is in there if it was to be, and set_raw_breakpoint
- does set it to 0). I implemented it because I thought it would be
- ***************
- *** 210,215 ****
- --- 218,234 ----
- struct block *exp_valid_block;
- /* Value of the watchpoint the last time we checked it. */
- value val;
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- + /* Address to memory break at. */
- + CORE_ADDR access_break_address;
- + /* length of block to look at */
- + int access_break_length;
- + /* expression for address to look at */
- + struct expression *access_break_exp;
- + /* set to mem_break_write, or mem_break_rw if this is a memory breakpoint.*/
- + enum access_break_type access_break_type;
- + #endif /* HAVE_MEM_BREAKPOINT */
- };
-
- /* Prototypes for breakpoint-related functions. */
- *** target.h Fri Feb 21 19:46:03 1992
- --- ../../gdb-4.6.new/gdb/target.h Fri Jul 24 15:32:56 1992
- ***************
- *** 39,45 ****
- never get to the process target). So when you push a file target,
- it goes into the file stratum, which is always below the process
- stratum. */
- !
- #include "bfd.h"
-
- enum strata {
- --- 39,45 ----
- never get to the process target). So when you push a file target,
- it goes into the file stratum, which is always below the process
- stratum. */
- ! #include "breakpoint.h"
- #include "bfd.h"
-
- enum strata {
- ***************
- *** 94,99 ****
- --- 94,106 ----
- *to_sections;
- struct section_table
- *to_sections_end;
- + #ifdef HAVE_MEM_BREAKPOINT
- + void (* to_init_access_breakpoint) PARAMS ((void));
- + int (*to_insert_access_breakpoint) PARAMS ((CORE_ADDR, int,
- + enum access_break_type, int));
- + int (* to_get_access_breakpoint_status) PARAMS ((void));
- + void (* to_clear_access_breakpoint_status) PARAMS ((void));
- + #endif /* HAVE_MEM_BREAKPOINT */
- int to_magic;
- /* Need sub-structure for target machine related rather than comm related? */
- };
- ***************
- *** 222,227 ****
- --- 229,266 ----
-
- #define target_files_info() \
- (*current_target->to_files_info) (current_target)
- +
- + #ifdef HAVE_MEM_BREAKPOINT
- + extern void
- + init_access_breakpoint PARAMS ((void));
- + extern int
- + insert_access_breakpoint PARAMS ((CORE_ADDR, int,
- + enum access_break_type, int));
- + extern int
- + get_access_breakpoint_status PARAMS ((void));
- + extern void
- + clear_access_breakpoint_status PARAMS ((void));
- +
- +
- + /* Initialize (clear), and set memory access breakpoints. This is probably
- + done with hardware debug registers in the cpu. Result is 0 for success,
- + or errno value for failure. If there is a failure there probably are not
- + any more debug registers left. */
- +
- + #define target_init_access_breakpoint() (*current_target->to_init_access_breakpoint)()
- +
- + #define target_insert_access_breakpoint(addr, len, type, bp_num) \
- + (*current_target->to_insert_access_breakpoint)(addr, len, type, bp_num)
- +
- + /* Return the breakpoint number that caused the memory access breakpoint.
- + Returns 0 if no memory acess breakpoint */
- + #define target_get_access_breakpoint_status() \
- + (*current_target->to_get_access_breakpoint_status)()
- +
- + /* Clear the memory breakpoint status. Called before execution is resumed*/
- + #define target_clear_access_breakpoint_status() \
- + (*current_target->to_clear_access_breakpoint_status)()
- + #endif /* HAVE_MEM_BREAKPOINT */
-
- /* Insert a breakpoint at address ADDR in the target machine.
- SAVE is a pointer to memory allocated for saving the
- ----------------------------------------------------------------
- Dave Daney daney@mermaid.micro.umn.edu
-
-
-