[GDB] Provide functions to manually enter GDB stub.
authorStefan Hajnoczi <stefanha@gmail.com>
Mon, 16 Jun 2008 13:42:22 +0000 (14:42 +0100)
committerMichael Brown <mcb30@etherboot.org>
Mon, 30 Jun 2008 18:19:48 +0000 (19:19 +0100)
src/core/gdbserial.c
src/core/gdbudp.c
src/include/gpxe/gdbserial.h [new file with mode: 0644]
src/include/gpxe/gdbudp.h [new file with mode: 0644]

index 2fecd5f..b0d5047 100644 (file)
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <gpxe/serial.h>
 #include <gpxe/gdbstub.h>
+#include <gpxe/gdbserial.h>
 
 struct gdb_transport serial_gdb_transport __gdb_transport;
 
@@ -39,3 +40,7 @@ struct gdb_transport serial_gdb_transport __gdb_transport = {
        .recv = gdbserial_recv,
        .send = gdbserial_send,
 };
+
+struct gdb_transport *gdbserial_configure ( void ) {
+       return &serial_gdb_transport;
+}
index 9dc80ee..c49a1bc 100644 (file)
@@ -19,6 +19,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <byteswap.h>
+#include <bios.h>
 #include <gpxe/iobuf.h>
 #include <gpxe/in.h>
 #include <gpxe/if_arp.h>
@@ -27,7 +28,7 @@
 #include <gpxe/udp.h>
 #include <gpxe/netdevice.h>
 #include <gpxe/gdbstub.h>
-#include <bios.h>
+#include <gpxe/gdbudp.h>
 
 /** @file
  *
@@ -43,7 +44,6 @@ struct gdb_transport udp_gdb_transport __gdb_transport;
 
 static struct net_device *netdev;
 static uint8_t dest_eth[ETH_ALEN];
-static uint8_t source_eth[ETH_ALEN];
 static struct sockaddr_in dest_addr;
 static struct sockaddr_in source_addr;
 
@@ -92,11 +92,12 @@ static size_t gdbudp_recv ( char *buf, size_t len ) {
                                arphdr->ar_op = htons ( ARPOP_REPLY );
                                memswap ( arp_sender_pa ( arphdr ), arp_target_pa ( arphdr ), sizeof ( struct in_addr ) );
                                memcpy ( arp_target_ha ( arphdr ), arp_sender_ha ( arphdr ), ETH_ALEN );
-                               memcpy ( arp_sender_ha ( arphdr ), source_eth, ETH_ALEN );
+                               memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, ETH_ALEN );
 
                                /* Fix up ethernet header */
                                ethhdr = iob_push ( iob, sizeof ( *ethhdr ) );
-                               memswap ( ethhdr->h_source, ethhdr->h_dest, ETH_ALEN );
+                               memcpy ( ethhdr->h_dest, ethhdr->h_source, ETH_ALEN );
+                               memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
 
                                netdev_tx ( netdev, iob );
                                continue; /* no need to free iob */
@@ -196,55 +197,55 @@ static void gdbudp_send ( const char *buf, size_t len ) {
        /* Ethernet header */
        ethhdr = iob_push ( iob, sizeof ( *ethhdr ) );
        memcpy ( ethhdr->h_dest, dest_eth, ETH_ALEN );
-       memcpy ( ethhdr->h_source, source_eth, ETH_ALEN );
+       memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
        ethhdr->h_protocol = htons ( ETH_P_IP );
 
        netdev_tx ( netdev, iob );
 }
 
-static int gdbudp_init ( int argc, char **argv ) {
+struct gdb_transport *gdbudp_configure ( const char *name, struct sockaddr_in *addr ) {
        struct settings *settings;
 
-       if ( argc != 1 ) {
-               printf ( "udp: missing <interface> argument\n" );
-               return 1;
-       }
-
        /* Release old network device */
        netdev_put ( netdev );
 
-       netdev = find_netdev ( argv[0] );
+       netdev = find_netdev ( name );
        if ( !netdev ) {
-               printf ( "%s: no such interface\n", argv[0] );
-               return 1;
+               return NULL;
        }
 
        /* Hold network device */
        netdev_get ( netdev );
 
-       if ( !netdev_link_ok ( netdev ) ) {
-               printf ( "%s: link not up\n", argv[0] );
-               netdev_put ( netdev );
-               netdev = NULL;
-               return 1;
+       /* Source UDP port */
+       source_addr.sin_port = ( addr && addr->sin_port ) ? addr->sin_port : htons ( DEFAULT_PORT );
+
+       /* Source IP address */
+       if ( addr && addr->sin_addr.s_addr ) {
+               source_addr.sin_addr.s_addr = addr->sin_addr.s_addr;
+       } else {
+               settings = netdev_settings ( netdev );
+               fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr );
+               if ( source_addr.sin_addr.s_addr == 0 ) {
+                       netdev_put ( netdev );
+                       netdev = NULL;
+                       return NULL;
+               }
        }
 
-       /* Load network settings from device.  We keep the MAC address,
-        * IP address, and UDP port.  The MAC and IP could be fetched
-        * from the network device each time they are used in rx/tx.
-        * Storing a separate copy makes it possible to use different
-        * MAC/IP settings than the network stack. */
-       memcpy ( source_eth, netdev->ll_addr, ETH_ALEN );
-       source_addr.sin_port = htons ( DEFAULT_PORT );
-       settings = netdev_settings ( netdev );
-       fetch_ipv4_setting ( settings, &ip_setting, &source_addr.sin_addr );
-       if ( source_addr.sin_addr.s_addr == 0 ) {
-               printf ( "%s: no IP address configured\n", argv[0] );
-               netdev_put ( netdev );
-               netdev = NULL;
+       return &udp_gdb_transport;
+}
+
+static int gdbudp_init ( int argc, char **argv ) {
+       if ( argc != 1 ) {
+               printf ( "udp: missing <interface> argument\n" );
                return 1;
        }
 
+       if ( !gdbudp_configure ( argv[0], NULL ) ) {
+               printf ( "%s: device does not exist or has no IP address\n", argv[0] );
+               return 1;
+       }
        return 0;
 }
 
diff --git a/src/include/gpxe/gdbserial.h b/src/include/gpxe/gdbserial.h
new file mode 100644 (file)
index 0000000..1863e90
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef _GPXE_GDBSERIAL_H
+#define _GPXE_GDBSERIAL_H
+
+/** @file
+ *
+ * GDB remote debugging over serial
+ *
+ */
+
+struct gdb_transport;
+
+/**
+ * Set up the serial transport
+ *
+ * @ret transport suitable for starting the GDB stub or NULL on error
+ */
+struct gdb_transport *gdbserial_configure ( void );
+
+#endif /* _GPXE_GDBSERIAL_H */
diff --git a/src/include/gpxe/gdbudp.h b/src/include/gpxe/gdbudp.h
new file mode 100644 (file)
index 0000000..1a99093
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef _GPXE_GDBUDP_H
+#define _GPXE_GDBUDP_H
+
+/** @file
+ *
+ * GDB remote debugging over UDP
+ *
+ */
+
+struct sockaddr_in;
+struct gdb_transport;
+
+/**
+ * Set up the UDP transport with network address
+ *
+ * @name network device name
+ * @addr IP address and UDP listen port, may be NULL and fields may be zero
+ * @ret transport suitable for starting the GDB stub or NULL on error
+ */
+struct gdb_transport *gdbudp_configure ( const char *name, struct sockaddr_in *addr );
+
+#endif /* _GPXE_GDBUDP_H */