X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsparcl-tdep.c;h=aa06747e97b8e439e3c46339823ce96139523598;hb=9579e000174ef881b7c0db330757b7b69409e751;hp=10d3618acf4b062708b4d865a9950c093c632a1e;hpb=d6acae6881b952e686f8f2e14fd0f9429d17c421;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/sparcl-tdep.c b/gdb/sparcl-tdep.c index 10d3618acf..aa06747e97 100644 --- a/gdb/sparcl-tdep.c +++ b/gdb/sparcl-tdep.c @@ -1,89 +1,89 @@ /* Target dependent code for the Fujitsu SPARClite for GDB, the GNU debugger. - Copyright 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright 1994, 1995, 1996, 1998, 1999, 2000, 2001 + Free Software Foundation, Inc. -This file is part of GDB. + This file is part of GDB. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include "gdbcore.h" #include "breakpoint.h" #include "target.h" #include "serial.h" +#include "regcache.h" #include -#if !defined(__GO32__) && !defined(_WIN32) +#if (!defined(__GO32__) && !defined(_WIN32)) || defined(__CYGWIN__) #define HAVE_SOCKETS #include -#include #include #include #include #endif -extern struct target_ops sparclite_ops; /* Forward decl */ -extern struct target_ops remote_ops; +static struct target_ops sparclite_ops; static char *remote_target_name = NULL; -static serial_t remote_desc = NULL; +static struct serial *remote_desc = NULL; static int serial_flag; #ifdef HAVE_SOCKETS static int udp_fd = -1; #endif -static serial_t open_tty PARAMS ((char *name)); -static int send_resp PARAMS ((serial_t desc, char c)); -static void close_tty PARAMS ((int ignore)); +static struct serial *open_tty (char *name); +static int send_resp (struct serial *desc, char c); +static void close_tty (void * ignore); #ifdef HAVE_SOCKETS -static int recv_udp_buf PARAMS ((int fd, unsigned char *buf, int len, int timeout)); -static int send_udp_buf PARAMS ((int fd, unsigned char *buf, int len)); +static int recv_udp_buf (int fd, unsigned char *buf, int len, int timeout); +static int send_udp_buf (int fd, unsigned char *buf, int len); #endif -static void sparclite_open PARAMS ((char *name, int from_tty)); -static void sparclite_close PARAMS ((int quitting)); -static void download PARAMS ((char *target_name, char *args, int from_tty, - void (*write_routine) (bfd *from_bfd, - asection *from_sec, - file_ptr from_addr, - bfd_vma to_addr, int len), - void (*start_routine) (bfd_vma entry))); -static void sparclite_serial_start PARAMS ((bfd_vma entry)); -static void sparclite_serial_write PARAMS ((bfd *from_bfd, asection *from_sec, - file_ptr from_addr, - bfd_vma to_addr, int len)); +static void sparclite_open (char *name, int from_tty); +static void sparclite_close (int quitting); +static void download (char *target_name, char *args, int from_tty, + void (*write_routine) (bfd * from_bfd, + asection * from_sec, + file_ptr from_addr, + bfd_vma to_addr, int len), + void (*start_routine) (bfd_vma entry)); +static void sparclite_serial_start (bfd_vma entry); +static void sparclite_serial_write (bfd * from_bfd, asection * from_sec, + file_ptr from_addr, + bfd_vma to_addr, int len); #ifdef HAVE_SOCKETS -static unsigned short calc_checksum PARAMS ((unsigned char *buffer, - int count)); -static void sparclite_udp_start PARAMS ((bfd_vma entry)); -static void sparclite_udp_write PARAMS ((bfd *from_bfd, asection *from_sec, - file_ptr from_addr, bfd_vma to_addr, - int len)); +static unsigned short calc_checksum (unsigned char *buffer, int count); +static void sparclite_udp_start (bfd_vma entry); +static void sparclite_udp_write (bfd * from_bfd, asection * from_sec, + file_ptr from_addr, bfd_vma to_addr, + int len); #endif -static void sparclite_download PARAMS ((char *filename, int from_tty)); +static void sparclite_download (char *filename, int from_tty); #define DDA2_SUP_ASI 0xb000000 #define DDA1_SUP_ASI 0xb0000 #define DDA2_ASI_MASK 0xff000000 -#define DDA1_ASI_MASK 0xff0000 +#define DDA1_ASI_MASK 0xff0000 #define DIA2_SUP_MODE 0x8000 #define DIA1_SUP_MODE 0x4000 #define DDA2_ENABLE 0x100 #define DDA1_ENABLE 0x80 #define DIA2_ENABLE 0x40 #define DIA1_ENABLE 0x20 -#define DSINGLE_STEP 0x10 +#define DSINGLE_STEP 0x10 /* not used */ #define DDV_TYPE_MASK 0xc #define DDV_TYPE_LOAD 0x0 #define DDV_TYPE_STORE 0x4 @@ -93,10 +93,7 @@ static void sparclite_download PARAMS ((char *filename, int from_tty)); #define DDV_MASK 0x1 int -sparclite_insert_watchpoint (addr, len, type) - CORE_ADDR addr; - int len; - int type; +sparclite_insert_watchpoint (CORE_ADDR addr, int len, int type) { CORE_ADDR dcr; @@ -112,7 +109,7 @@ sparclite_insert_watchpoint (addr, len, type) write_register (DDV1_REGNUM, 0); write_register (DDV2_REGNUM, 0xffffffff); dcr |= (DDV_TYPE_LOAD & (~DDV_COND & ~DDV_MASK)); - } + } else if (type == 0) { write_register (DDV1_REGNUM, 0); @@ -156,13 +153,10 @@ sparclite_insert_watchpoint (addr, len, type) return -1; return 0; -} +} int -sparclite_remove_watchpoint (addr, len, type) - CORE_ADDR addr; - int len; - int type; +sparclite_remove_watchpoint (CORE_ADDR addr, int len, int type) { CORE_ADDR dcr, dda1, dda2; @@ -181,14 +175,12 @@ sparclite_remove_watchpoint (addr, len, type) } int -sparclite_insert_hw_breakpoint (addr, len) - CORE_ADDR addr; - int len; +sparclite_insert_hw_breakpoint (CORE_ADDR addr, int len) { CORE_ADDR dcr; dcr = read_register (DCR_REGNUM); - + if (!(dcr & DIA1_ENABLE)) { write_register (DIA1_REGNUM, addr); @@ -206,16 +198,14 @@ sparclite_insert_hw_breakpoint (addr, len) } int -sparclite_remove_hw_breakpoint (addr, shadow) - CORE_ADDR addr; - int shadow; +sparclite_remove_hw_breakpoint (CORE_ADDR addr, int shadow) { CORE_ADDR dcr, dia1, dia2; dcr = read_register (DCR_REGNUM); dia1 = read_register (DIA1_REGNUM); dia2 = read_register (DIA2_REGNUM); - + if ((dcr & DIA1_ENABLE) && addr == dia1) write_register (DCR_REGNUM, (dcr & ~DIA1_ENABLE)); else if ((dcr & DIA2_ENABLE) && addr == dia2) @@ -227,11 +217,12 @@ sparclite_remove_hw_breakpoint (addr, shadow) } int -sparclite_check_watch_resources (type, cnt, ot) - int type; - int cnt; - int ot; +sparclite_check_watch_resources (int type, int cnt, int ot) { + /* Watchpoints not supported on simulator. */ + if (strcmp (target_shortname, "sim") == 0) + return 0; + if (type == bp_hardware_breakpoint) { if (TARGET_HW_BREAK_LIMIT == 0) @@ -252,7 +243,7 @@ sparclite_check_watch_resources (type, cnt, ot) } CORE_ADDR -sparclite_stopped_data_address () +sparclite_stopped_data_address (void) { CORE_ADDR dsr, dda1, dda2; @@ -268,28 +259,27 @@ sparclite_stopped_data_address () return 0; } -static serial_t -open_tty (name) - char *name; +static struct serial * +open_tty (char *name) { - serial_t desc; + struct serial *desc; - desc = SERIAL_OPEN (name); + desc = serial_open (name); if (!desc) perror_with_name (name); if (baud_rate != -1) { - if (SERIAL_SETBAUDRATE (desc, baud_rate)) + if (serial_setbaudrate (desc, baud_rate)) { - SERIAL_CLOSE (desc); + serial_close (desc); perror_with_name (name); } } - SERIAL_RAW (desc); + serial_raw (desc); - SERIAL_FLUSH_INPUT (desc); + serial_flush_input (desc); return desc; } @@ -297,13 +287,12 @@ open_tty (name) /* Read a single character from the remote end, masking it down to 7 bits. */ static int -readchar (desc, timeout) - serial_t desc; - int timeout; +readchar (struct serial *desc, int timeout) { int ch; + char s[10]; - ch = SERIAL_READCHAR (desc, timeout); + ch = serial_readchar (desc, timeout); switch (ch) { @@ -314,37 +303,54 @@ readchar (desc, timeout) case SERIAL_TIMEOUT: error ("SPARClite remote timeout"); default: + if (remote_debug > 0) + { + sprintf (s, "[%02x]", ch & 0xff); + puts_debug ("read -->", s, "<--"); + } return ch; } } +static void +debug_serial_write (struct serial *desc, char *buf, int len) +{ + char s[10]; + + serial_write (desc, buf, len); + if (remote_debug > 0) + { + while (len-- > 0) + { + sprintf (s, "[%02x]", *buf & 0xff); + puts_debug ("Sent -->", s, "<--"); + buf++; + } + } +} + + static int -send_resp (desc, c) - serial_t desc; - char c; +send_resp (struct serial *desc, char c) { - SERIAL_WRITE (desc, &c, 1); - return readchar (desc, 2); + debug_serial_write (desc, &c, 1); + return readchar (desc, remote_timeout); } static void -close_tty (ignore) - int ignore; +close_tty (void *ignore) { if (!remote_desc) return; - SERIAL_CLOSE (remote_desc); + serial_close (remote_desc); remote_desc = NULL; } #ifdef HAVE_SOCKETS static int -recv_udp_buf (fd, buf, len, timeout) - int fd, len; - unsigned char *buf; - int timeout; +recv_udp_buf (int fd, unsigned char *buf, int len, int timeout) { int cc; fd_set readfds; @@ -376,9 +382,7 @@ recv_udp_buf (fd, buf, len, timeout) } static int -send_udp_buf (fd, buf, len) - int fd, len; - unsigned char *buf; +send_udp_buf (int fd, unsigned char *buf, int len) { int cc; @@ -395,9 +399,7 @@ send_udp_buf (fd, buf, len) #endif /* HAVE_SOCKETS */ static void -sparclite_open (name, from_tty) - char *name; - int from_tty; +sparclite_open (char *name, int from_tty) { struct cleanup *old_chain; int c; @@ -411,9 +413,9 @@ sparclite_open (name, from_tty) unpush_target (&sparclite_ops); if (remote_target_name) - free (remote_target_name); + xfree (remote_target_name); - remote_target_name = strsave (name); + remote_target_name = xstrdup (name); /* We need a 'serial' or 'udp' keyword to disambiguate host:port, which can mean either a serial port on a terminal server, or the IP address of a @@ -425,7 +427,8 @@ sparclite_open (name, from_tty) if (p) { *p++ = '\000'; - while ((*p != '\000') && isspace (*p)) p++; + while ((*p != '\000') && isspace (*p)) + p++; if (strncmp (name, "serial", strlen (name)) == 0) serial_flag = 1; @@ -449,7 +452,7 @@ or: target sparclite udp host"); { remote_desc = open_tty (p); - old_chain = make_cleanup (close_tty, 0); + old_chain = make_cleanup (close_tty, 0 /*ignore*/); c = send_resp (remote_desc, 0x00); @@ -482,17 +485,17 @@ or: target sparclite udp host"); old_chain = make_cleanup (close, udp_fd); sockaddr.sin_family = PF_INET; - sockaddr.sin_port = htons(7000); + sockaddr.sin_port = htons (7000); memcpy (&sockaddr.sin_addr.s_addr, he->h_addr, sizeof (struct in_addr)); - if (connect (udp_fd, &sockaddr, sizeof(sockaddr))) + if (connect (udp_fd, &sockaddr, sizeof (sockaddr))) perror_with_name ("Connect failed"); buffer[0] = 0x5; buffer[1] = 0; - send_udp_buf (udp_fd, buffer, 2); /* Request version */ - cc = recv_udp_buf (udp_fd, buffer, sizeof(buffer), 5); /* Get response */ + send_udp_buf (udp_fd, buffer, 2); /* Request version */ + cc = recv_udp_buf (udp_fd, buffer, sizeof (buffer), 5); /* Get response */ if (cc == 0) error ("SPARClite isn't responding."); @@ -513,28 +516,23 @@ or: target sparclite udp host"); } static void -sparclite_close (quitting) - int quitting; +sparclite_close (int quitting) { if (serial_flag) close_tty (0); #ifdef HAVE_SOCKETS - else - if (udp_fd != -1) - close (udp_fd); + else if (udp_fd != -1) + close (udp_fd); #endif } #define LOAD_ADDRESS 0x40000000 static void -download (target_name, args, from_tty, write_routine, start_routine) - char *target_name; - char *args; - int from_tty; - void (*write_routine) PARAMS ((bfd *from_bfd, asection *from_sec, - file_ptr from_addr, bfd_vma to_addr, int len)); - void (*start_routine) PARAMS ((bfd_vma entry)); +download (char *target_name, char *args, int from_tty, + void (*write_routine) (bfd *from_bfd, asection *from_sec, + file_ptr from_addr, bfd_vma to_addr, int len), + void (*start_routine) (bfd_vma entry)) { struct cleanup *old_chain; asection *section; @@ -554,11 +552,13 @@ download (target_name, args, from_tty, write_routine, start_routine) { char *arg; - while (isspace (*args)) args++; + while (isspace (*args)) + args++; arg = args; - while ((*args != '\000') && !isspace (*args)) args++; + while ((*args != '\000') && !isspace (*args)) + args++; if (*args != '\000') *args++ = '\000'; @@ -582,25 +582,53 @@ download (target_name, args, from_tty, write_routine, start_routine) perror_with_name (filename); return; } - old_chain = make_cleanup (bfd_close, pbfd); + old_chain = make_cleanup_bfd_close (pbfd); - if (!bfd_check_format (pbfd, bfd_object)) + if (!bfd_check_format (pbfd, bfd_object)) error ("\"%s\" is not an object file: %s", filename, bfd_errmsg (bfd_get_error ())); - for (section = pbfd->sections; section; section = section->next) + for (section = pbfd->sections; section; section = section->next) { if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) { bfd_vma section_address; bfd_size_type section_size; file_ptr fptr; + const char *section_name; + + section_name = bfd_get_section_name (pbfd, section); section_address = bfd_get_section_vma (pbfd, section); + /* Adjust sections from a.out files, since they don't carry their addresses with. */ if (bfd_get_flavour (pbfd) == bfd_target_aout_flavour) - section_address += LOAD_ADDRESS; + { + if (strcmp (section_name, ".text") == 0) + section_address = bfd_get_start_address (pbfd); + else if (strcmp (section_name, ".data") == 0) + { + /* Read the first 8 bytes of the data section. + There should be the string 'DaTa' followed by + a word containing the actual section address. */ + struct data_marker + { + char signature[4]; /* 'DaTa' */ + unsigned char sdata[4]; /* &sdata */ + } + marker; + bfd_get_section_contents (pbfd, section, &marker, 0, + sizeof (marker)); + if (strncmp (marker.signature, "DaTa", 4) == 0) + { + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + section_address = bfd_getb32 (marker.sdata); + else + section_address = bfd_getl32 (marker.sdata); + } + } + } section_size = bfd_get_section_size_before_reloc (section); @@ -650,8 +678,7 @@ download (target_name, args, from_tty, write_routine, start_routine) } static void -sparclite_serial_start (entry) - bfd_vma entry; +sparclite_serial_start (bfd_vma entry) { char buffer[5]; int i; @@ -659,26 +686,22 @@ sparclite_serial_start (entry) buffer[0] = 0x03; store_unsigned_integer (buffer + 1, 4, entry); - SERIAL_WRITE (remote_desc, buffer, 1 + 4); - i = readchar (remote_desc, 2); + debug_serial_write (remote_desc, buffer, 1 + 4); + i = readchar (remote_desc, remote_timeout); if (i != 0x55) error ("Can't start SparcLite. Error code %d\n", i); } static void -sparclite_serial_write (from_bfd, from_sec, from_addr, to_addr, len) - bfd *from_bfd; - asection *from_sec; - file_ptr from_addr; - bfd_vma to_addr; - int len; +sparclite_serial_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, + bfd_vma to_addr, int len) { - char buffer[4 + 4 + WRITESIZE]; /* addr + len + data */ + char buffer[4 + 4 + WRITESIZE]; /* addr + len + data */ unsigned char checksum; int i; - store_unsigned_integer (buffer, 4, to_addr); /* Address */ - store_unsigned_integer (buffer + 4, 4, len); /* Length */ + store_unsigned_integer (buffer, 4, to_addr); /* Address */ + store_unsigned_integer (buffer + 4, 4, len); /* Length */ bfd_get_section_contents (from_bfd, from_sec, buffer + 8, from_addr, len); @@ -691,8 +714,8 @@ sparclite_serial_write (from_bfd, from_sec, from_addr, to_addr, len) if (i != 0x5a) error ("Bad response from load command (0x%x)", i); - SERIAL_WRITE (remote_desc, buffer, 4 + 4 + len); - i = readchar (remote_desc, 2); + debug_serial_write (remote_desc, buffer, 4 + 4 + len); + i = readchar (remote_desc, remote_timeout); if (i != checksum) error ("Bad checksum from load command (0x%x)", i); @@ -701,9 +724,7 @@ sparclite_serial_write (from_bfd, from_sec, from_addr, to_addr, len) #ifdef HAVE_SOCKETS static unsigned short -calc_checksum (buffer, count) - unsigned char *buffer; - int count; +calc_checksum (unsigned char *buffer, int count) { unsigned short checksum; @@ -718,8 +739,7 @@ calc_checksum (buffer, count) } static void -sparclite_udp_start (entry) - bfd_vma entry; +sparclite_udp_start (bfd_vma entry) { unsigned char buffer[6]; int i; @@ -731,20 +751,16 @@ sparclite_udp_start (entry) buffer[4] = entry >> 8; buffer[5] = entry; - send_udp_buf (udp_fd, buffer, 6); /* Send start addr */ - i = recv_udp_buf (udp_fd, buffer, sizeof(buffer), -1); /* Get response */ + send_udp_buf (udp_fd, buffer, 6); /* Send start addr */ + i = recv_udp_buf (udp_fd, buffer, sizeof (buffer), -1); /* Get response */ if (i < 1 || buffer[0] != 0x55) error ("Failed to take start address."); } static void -sparclite_udp_write (from_bfd, from_sec, from_addr, to_addr, len) - bfd *from_bfd; - asection *from_sec; - file_ptr from_addr; - bfd_vma to_addr; - int len; +sparclite_udp_write (bfd *from_bfd, asection *from_sec, file_ptr from_addr, + bfd_vma to_addr, int len) { unsigned char buffer[2000]; unsigned short checksum; @@ -815,71 +831,39 @@ sparclite_udp_write (from_bfd, from_sec, from_addr, to_addr, len) #endif /* HAVE_SOCKETS */ static void -sparclite_download (filename, from_tty) - char *filename; - int from_tty; +sparclite_download (char *filename, int from_tty) { if (!serial_flag) #ifdef HAVE_SOCKETS download (remote_target_name, filename, from_tty, sparclite_udp_write, sparclite_udp_start); #else - abort (); /* sparclite_open should prevent this! */ + internal_error (__FILE__, __LINE__, "failed internal consistency check"); /* sparclite_open should prevent this! */ #endif else download (remote_target_name, filename, from_tty, sparclite_serial_write, sparclite_serial_start); } -/* Define the target subroutine names */ +/* Set up the sparclite target vector. */ -static struct target_ops sparclite_ops = +static void +init_sparclite_ops (void) { - "sparclite", /* to_shortname */ - "SPARClite remote target", /* to_longname */ - "Use a remote SPARClite target board via a serial line, using a gdb-specific protocol.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya).", /* to_doc */ - sparclite_open, /* to_open */ - sparclite_close, /* to_close */ - 0, /* to_attach */ - 0, /* to_detach */ - 0, /* to_resume */ - 0, /* to_wait */ - 0, /* to_fetch_registers */ - 0, /* to_store_registers */ - 0, /* to_prepare_to_store */ - 0, /* to_xfer_memory */ - 0, /* to_files_info */ - 0, /* to_insert_breakpoint */ - 0, /* to_remove_breakpoint */ - 0, /* to_terminal_init */ - 0, /* to_terminal_inferior */ - 0, /* to_terminal_ours_for_output */ - 0, /* to_terminal_ours */ - 0, /* to_terminal_info */ - 0, /* to_kill */ - sparclite_download, /* to_load */ - 0, /* to_lookup_symbol */ - 0, /* to_create_inferior */ - 0, /* to_mourn_inferior */ - 0, /* to_can_run */ - 0, /* to_notice_signals */ - 0, /* to_thread_alive */ - 0, /* to_stop */ - download_stratum, /* to_stratum */ - 0, /* to_next */ - 0, /* to_has_all_memory */ - 0, /* to_has_memory */ - 0, /* to_has_stack */ - 0, /* to_has_registers */ - 0, /* to_has_execution */ - 0, /* sections */ - 0, /* sections_end */ - OPS_MAGIC /* to_magic */ - }; + sparclite_ops.to_shortname = "sparclite"; + sparclite_ops.to_longname = "SPARClite download target"; + sparclite_ops.to_doc = "Download to a remote SPARClite target board via serial of UDP.\n\ +Specify the device it is connected to (e.g. /dev/ttya)."; + sparclite_ops.to_open = sparclite_open; + sparclite_ops.to_close = sparclite_close; + sparclite_ops.to_load = sparclite_download; + sparclite_ops.to_stratum = download_stratum; + sparclite_ops.to_magic = OPS_MAGIC; +} void -_initialize_sparcl_tdep () +_initialize_sparcl_tdep (void) { + init_sparclite_ops (); add_target (&sparclite_ops); }