2 * Copyright (c) 2000-2019 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
30 * Copyright (c) 1982, 1986, 1993
31 * The Regents of the University of California. All rights reserved.
35 * Kernel Debugging Protocol UDP implementation.
38 #include <mach/boolean.h>
39 #include <mach/mach_types.h>
40 #include <mach/exception_types.h>
41 #include <kern/cpu_data.h>
42 #include <kern/debug.h>
43 #include <kern/clock.h>
45 #include <kdp/kdp_core.h>
46 #include <kdp/kdp_internal.h>
47 #if (MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING)
48 #include <kdp/kdp_en_debugger.h>
50 #include <kdp/kdp_callout.h>
51 #include <kdp/kdp_udp.h>
52 #include <kdp/kdp_core.h>
54 #include <kdp/kdp_serial.h>
57 #include <vm/vm_map.h>
58 #include <vm/vm_protos.h>
59 #include <vm/vm_kern.h> /* kernel_map */
61 #include <mach/memory_object_types.h>
62 #include <machine/pal_routines.h>
64 #include <sys/msgbuf.h>
66 /* we just want the link status flags, so undef KERNEL_PRIVATE for this
69 #include <net/if_media.h>
70 #define KERNEL_PRIVATE
74 #include <IOKit/IOPlatformExpert.h>
75 #include <libkern/version.h>
79 extern unsigned int not_in_kdp
;
80 extern int kdp_snapshot
;
82 #ifdef CONFIG_KDP_INTERACTIVE_DEBUGGING
84 extern int inet_aton(const char *, struct kdp_in_addr
*); /* in libkern */
85 extern char *inet_ntoa_r(struct kdp_in_addr ina
, char *buf
,
86 size_t buflen
); /* in libkern */
88 #define DO_ALIGN 1 /* align all packet data accesses */
89 #define KDP_SERIAL_IPADDR 0xABADBABE /* IP address used for serial KDP */
90 #define LINK_UP_STATUS (IFM_AVALID | IFM_ACTIVE)
92 extern int kdp_getc(void);
93 extern int reattach_wait
;
95 static u_short ip_id
; /* ip packet ctr, for ids */
97 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
100 * UDP protocol implementation.
101 * Per RFC 768, August, 1980.
103 #define UDP_TTL 60 /* default time to live for UDP packets */
104 static u_char udp_ttl
= UDP_TTL
;
105 static unsigned char exception_seq
;
108 uint32_t ih_next
, ih_prev
; /* for protocol sequence q's */
109 u_char ih_x1
; /* (unused) */
110 u_char ih_pr
; /* protocol */
111 short ih_len
; /* protocol length */
112 struct kdp_in_addr ih_src
; /* source internet address */
113 struct kdp_in_addr ih_dst
; /* destination internet address */
117 u_short uh_sport
; /* source port */
118 u_short uh_dport
; /* destination port */
119 short uh_ulen
; /* udp length */
120 u_short uh_sum
; /* udp checksum */
123 struct kdp_udpiphdr
{
124 struct kdp_ipovly ui_i
; /* overlaid ip structure */
125 struct kdp_udphdr ui_u
; /* udp header */
127 #define ui_next ui_i.ih_next
128 #define ui_prev ui_i.ih_prev
129 #define ui_x1 ui_i.ih_x1
130 #define ui_pr ui_i.ih_pr
131 #define ui_len ui_i.ih_len
132 #define ui_src ui_i.ih_src
133 #define ui_dst ui_i.ih_dst
134 #define ui_sport ui_u.uh_sport
135 #define ui_dport ui_u.uh_dport
136 #define ui_ulen ui_u.uh_ulen
137 #define ui_sum ui_u.uh_sum
144 #ifdef __LITTLE_ENDIAN__
145 ip_xhl
:4, /* header length */
146 ip_xv
:4, /* version */
147 ip_xtos
:8, /* type of service */
148 ip_xlen
:16; /* total length */
150 #ifdef __BIG_ENDIAN__
151 ip_xv
:4, /* version */
152 ip_xhl
:4, /* header length */
153 ip_xtos
:8, /* type of service */
154 ip_xlen
:16; /* total length */
158 u_short ip_id
; /* identification */
159 short ip_off
; /* fragment offset field */
160 #define IP_DF 0x4000 /* dont fragment flag */
161 #define IP_MF 0x2000 /* more fragments flag */
162 #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
163 u_char ip_ttl
; /* time to live */
164 u_char ip_p
; /* protocol */
165 u_short ip_sum
; /* checksum */
166 struct kdp_in_addr ip_src
, ip_dst
; /* source and dest address */
168 #define ip_v ip_vhltl.ip_x.ip_xv
169 #define ip_hl ip_vhltl.ip_x.ip_xhl
170 #define ip_tos ip_vhltl.ip_x.ip_xtos
171 #define ip_len ip_vhltl.ip_x.ip_xlen
173 #define IPPROTO_UDP 17
176 #define ETHERTYPE_IP 0x0800 /* IP protocol */
179 * Ethernet Address Resolution Protocol.
181 * See RFC 826 for protocol description. Structure below is adapted
182 * to resolving internet addresses. Field names used correspond to
186 #define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
189 u_short ar_hrd
; /* format of hardware address */
190 #define ARPHRD_ETHER 1 /* ethernet hardware format */
191 #define ARPHRD_FRELAY 15 /* frame relay hardware format */
192 u_short ar_pro
; /* format of protocol address */
193 u_char ar_hln
; /* length of hardware address */
194 u_char ar_pln
; /* length of protocol address */
195 u_short ar_op
; /* one of: */
196 #define ARPOP_REQUEST 1 /* request to resolve address */
197 #define ARPOP_REPLY 2 /* response to previous request */
198 #define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
199 #define ARPOP_REVREPLY 4 /* response giving protocol address */
200 #define ARPOP_INVREQUEST 8 /* request to identify peer */
201 #define ARPOP_INVREPLY 9 /* response identifying peer */
204 struct kdp_ether_arp
{
205 struct kdp_arphdr ea_hdr
; /* fixed-size header */
206 u_char arp_sha
[ETHER_ADDR_LEN
]; /* sender hardware address */
207 u_char arp_spa
[4]; /* sender protocol address */
208 u_char arp_tha
[ETHER_ADDR_LEN
]; /* target hardware address */
209 u_char arp_tpa
[4]; /* target protocol address */
211 #define arp_hrd ea_hdr.ar_hrd
212 #define arp_pro ea_hdr.ar_pro
213 #define arp_hln ea_hdr.ar_hln
214 #define arp_pln ea_hdr.ar_pln
215 #define arp_op ea_hdr.ar_op
217 #define ETHERMTU 1500
218 #define ETHERHDRSIZE 14
220 #define KDP_MAXPACKET (ETHERHDRSIZE + ETHERMTU + ETHERCRC)
223 unsigned char data
[KDP_MAXPACKET
];
224 unsigned int off
, len
;
228 struct kdp_manual_pkt manual_pkt
;
232 struct kdp_in_addr in
;
233 struct kdp_ether_addr ea
;
236 struct kdp_in_addr in
;
237 struct kdp_ether_addr ea
;
242 *exception_message
[] = {
244 "Memory access", /* EXC_BAD_ACCESS */
245 "Failed instruction", /* EXC_BAD_INSTRUCTION */
246 "Arithmetic", /* EXC_ARITHMETIC */
247 "Emulation", /* EXC_EMULATION */
248 "Software", /* EXC_SOFTWARE */
249 "Breakpoint" /* EXC_BREAKPOINT */
252 volatile int kdp_flag
= 0;
253 boolean_t kdp_corezip_disabled
= 0;
255 kdp_send_t kdp_en_send_pkt
;
256 static kdp_receive_t kdp_en_recv_pkt
;
257 static kdp_link_t kdp_en_linkstatus
;
258 static kdp_mode_t kdp_en_setmode
;
260 #if CONFIG_SERIAL_KDP
261 static void kdp_serial_send(void *rpkt
, unsigned int rpkt_len
);
262 #define KDP_SERIAL_ENABLED() (kdp_en_send_pkt == kdp_serial_send)
264 #define KDP_SERIAL_ENABLED() (0)
267 static uint32_t kdp_current_ip_address
= 0;
268 static struct kdp_ether_addr kdp_current_mac_address
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
269 static void *kdp_current_ifp
;
271 static void kdp_handler( void *);
273 static uint32_t panic_server_ip
= 0;
274 static uint32_t parsed_router_ip
= 0;
275 static uint32_t router_ip
= 0;
276 static uint32_t target_ip
= 0;
278 static boolean_t save_ip_in_nvram
= FALSE
;
280 static volatile boolean_t panicd_specified
= FALSE
;
281 static boolean_t router_specified
= FALSE
;
282 static boolean_t corename_specified
= FALSE
;
283 static unsigned short panicd_port
= CORE_REMOTE_PORT
;
285 static struct kdp_ether_addr etherbroadcastaddr
= {.ether_addr_octet
= {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
287 static struct kdp_ether_addr router_mac
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
288 static struct kdp_ether_addr destination_mac
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
289 static struct kdp_ether_addr temp_mac
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
290 static struct kdp_ether_addr current_resolved_MAC
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
292 static boolean_t flag_panic_dump_in_progress
= FALSE
;
293 static boolean_t flag_router_mac_initialized
= FALSE
;
294 static boolean_t flag_dont_abort_panic_dump
= FALSE
;
296 static boolean_t flag_arp_resolved
= FALSE
;
298 static unsigned int panic_timeout
= 100000;
299 static unsigned short last_panic_port
= CORE_REMOTE_PORT
;
301 #define KDP_THROTTLE_VALUE (10ULL * NSEC_PER_SEC)
303 uint32_t kdp_crashdump_pkt_size
= 512;
304 #define KDP_LARGE_CRASHDUMP_PKT_SIZE (1440 - 6 - sizeof(struct kdp_udpiphdr))
305 static char panicd_ip_str
[20];
306 static char router_ip_str
[20];
307 static char corename_str
[100];
309 static unsigned int panic_block
= 0;
310 volatile unsigned int kdp_trigger_core_dump
= 0;
311 __private_extern__
volatile unsigned int flag_kdp_trigger_reboot
= 0;
314 extern unsigned int disableConsoleOutput
;
316 extern void kdp_call(void);
318 void * kdp_get_interface(void);
319 void kdp_set_gateway_mac(void *gatewaymac
);
320 void kdp_set_ip_and_mac_addresses(struct kdp_in_addr
*ipaddr
, struct kdp_ether_addr
*);
321 void kdp_set_interface(void *interface
, const struct kdp_ether_addr
*macaddr
);
323 void kdp_disable_arp(void);
324 static void kdp_arp_reply(struct kdp_ether_arp
*);
325 static void kdp_process_arp_reply(struct kdp_ether_arp
*);
326 static boolean_t
kdp_arp_resolve(uint32_t, struct kdp_ether_addr
*);
328 static volatile unsigned kdp_reentry_deadline
;
330 static uint32_t kdp_crashdump_feature_mask
= KDP_FEATURE_LARGE_CRASHDUMPS
| KDP_FEATURE_LARGE_PKT_SIZE
;
331 uint32_t kdp_feature_large_crashdumps
, kdp_feature_large_pkt_size
;
333 char kdp_kernelversion_string
[256];
335 static boolean_t gKDPDebug
= FALSE
;
337 #define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
339 #define SBLOCKSZ (2048)
340 uint64_t kdp_dump_start_time
= 0;
341 uint64_t kdp_min_superblock_dump_time
= ~1ULL;
342 uint64_t kdp_max_superblock_dump_time
= 0;
343 uint64_t kdp_superblock_dump_time
= 0;
344 uint64_t kdp_superblock_dump_start_time
= 0;
349 kdp_ml_enter_debugger_wrapper(__unused
void *param0
, __unused
void *param1
)
351 kdp_ml_enter_debugger();
355 kdp_timer_callout_init(void)
357 kdp_timer_call
= thread_call_allocate(kdp_ml_enter_debugger_wrapper
, NULL
);
361 /* only send/receive data if the link is up */
365 static int first
= 0;
367 if (!kdp_en_linkstatus
) {
371 while (((*kdp_en_linkstatus
)() & LINK_UP_STATUS
) != LINK_UP_STATUS
) {
377 printf("Waiting for link to become available.\n");
378 kprintf("Waiting for link to become available.\n");
384 kdp_send_data(void *packet
, unsigned int len
)
387 (*kdp_en_send_pkt
)(packet
, len
);
392 kdp_receive_data(void *packet
, unsigned int *len
, unsigned int timeout
)
395 (*kdp_en_recv_pkt
)(packet
, len
, timeout
);
400 kdp_register_link(kdp_link_t link
, kdp_mode_t mode
)
402 kdp_en_linkstatus
= link
;
403 kdp_en_setmode
= mode
;
407 kdp_unregister_link(__unused kdp_link_t link
, __unused kdp_mode_t mode
)
409 kdp_en_linkstatus
= NULL
;
410 kdp_en_setmode
= NULL
;
414 kdp_register_send_receive(
416 kdp_receive_t receive
)
418 unsigned int debug
= debug_boot_arg
;
420 if (!kernel_debugging_allowed()) {
428 kdp_en_send_pkt
= send
;
429 kdp_en_recv_pkt
= receive
;
431 if (debug
& DB_KDP_BP_DIS
) {
432 kdp_flag
|= KDP_BP_DIS
;
434 if (debug
& DB_KDP_GETC_ENA
) {
435 kdp_flag
|= KDP_GETC_ENA
;
437 if (debug
& DB_ARP
) {
441 if (debug
& DB_KERN_DUMP_ON_PANIC
) {
442 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
444 if (debug
& DB_KERN_DUMP_ON_NMI
) {
445 kdp_flag
|= PANIC_CORE_ON_NMI
;
448 if (debug
& DB_DBG_POST_CORE
) {
449 kdp_flag
|= DBG_POST_CORE
;
452 if (debug
& DB_PANICLOG_DUMP
) {
453 kdp_flag
|= PANIC_LOG_DUMP
;
456 kdp_corezip_disabled
= (0 != (debug
& DB_DISABLE_GZIP_CORE
));
458 if (PE_parse_boot_argn("_panicd_ip", panicd_ip_str
, sizeof(panicd_ip_str
))) {
459 panicd_specified
= TRUE
;
462 if ((debug
& DB_REBOOT_POST_CORE
) && (panicd_specified
== TRUE
)) {
463 kdp_flag
|= REBOOT_POST_CORE
;
466 if (PE_parse_boot_argn("_router_ip", router_ip_str
, sizeof(router_ip_str
))) {
467 router_specified
= TRUE
;
470 if (!PE_parse_boot_argn("panicd_port", &panicd_port
, sizeof(panicd_port
))) {
471 panicd_port
= CORE_REMOTE_PORT
;
474 if (PE_parse_boot_argn("_panicd_corename", &corename_str
, sizeof(corename_str
))) {
475 corename_specified
= TRUE
;
478 kdp_flag
|= KDP_READY
;
480 current_debugger
= KDP_CUR_DB
;
481 if ((kdp_current_ip_address
!= 0) && halt_in_debugger
) {
483 halt_in_debugger
= 0;
488 kdp_unregister_send_receive(
489 __unused kdp_send_t send
,
490 __unused kdp_receive_t receive
)
492 if (current_debugger
== KDP_CUR_DB
) {
493 current_debugger
= NO_CUR_DB
;
495 kdp_flag
&= ~KDP_READY
;
496 kdp_en_send_pkt
= NULL
;
497 kdp_en_recv_pkt
= NULL
;
501 kdp_schedule_debugger_reentry(unsigned interval
)
505 clock_interval_to_deadline(interval
, 1000 * 1000, &deadline
);
506 thread_call_enter_delayed(kdp_timer_call
, deadline
);
515 bcopy((char *)src
, (char *)dst
, sizeof(struct kdp_ether_addr
));
518 static unsigned short
524 unsigned int high
, low
, sum
;
534 sum
= (high
<< 8) + low
;
535 sum
= (sum
>> 16) + (sum
& USHRT_MAX
);
536 sum
= (sum
> USHRT_MAX
) ? sum
- USHRT_MAX
: sum
;
538 return (unsigned short)sum
;
543 unsigned short reply_port
,
544 const boolean_t sideband
547 struct kdp_udpiphdr aligned_ui
, *ui
= &aligned_ui
;
548 struct kdp_ip aligned_ip
, *ip
= &aligned_ip
;
549 struct kdp_in_addr tmp_ipaddr
;
550 struct kdp_ether_addr tmp_enaddr
;
551 struct kdp_ether_header
*eh
= NULL
;
554 kdp_panic("kdp_reply: no input packet");
557 /* Packet size cannot be larger than the static space allocated for it. */
558 if (pkt
.len
> KDP_MAXPACKET
) {
559 kdp_panic("kdp_send: packet too large (%d > %u)", pkt
.len
, KDP_MAXPACKET
);
562 pkt
.off
-= (unsigned int)sizeof(struct kdp_udpiphdr
);
565 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
567 ui
= (struct kdp_udpiphdr
*)&pkt
.data
[pkt
.off
];
569 ui
->ui_next
= ui
->ui_prev
= 0;
571 ui
->ui_pr
= IPPROTO_UDP
;
572 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof(struct kdp_udphdr
));
573 tmp_ipaddr
= ui
->ui_src
;
574 ui
->ui_src
= ui
->ui_dst
;
575 ui
->ui_dst
= tmp_ipaddr
;
576 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
577 ui
->ui_dport
= reply_port
;
578 ui
->ui_ulen
= ui
->ui_len
;
581 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
582 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
584 ip
= (struct kdp_ip
*)&pkt
.data
[pkt
.off
];
586 ip
->ip_len
= htons((ushort_t
)(sizeof(struct kdp_udpiphdr
) + pkt
.len
));
587 ip
->ip_v
= IPVERSION
;
588 ip
->ip_id
= htons(ip_id
++);
589 ip
->ip_hl
= sizeof(struct kdp_ip
) >> 2;
590 ip
->ip_ttl
= udp_ttl
;
592 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
594 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
597 pkt
.len
+= (unsigned int)sizeof(struct kdp_udpiphdr
);
599 pkt
.off
-= (unsigned int)sizeof(struct kdp_ether_header
);
601 eh
= (struct kdp_ether_header
*)&pkt
.data
[pkt
.off
];
602 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
603 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
604 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
605 eh
->ether_type
= htons(ETHERTYPE_IP
);
607 pkt
.len
+= (unsigned int)sizeof(struct kdp_ether_header
);
609 // save reply for possible retransmission
611 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(saved_reply
));
614 kdp_send_data(&pkt
.data
[pkt
.off
], pkt
.len
);
616 // increment expected sequence number
624 unsigned short remote_port
627 struct kdp_udpiphdr aligned_ui
, *ui
= &aligned_ui
;
628 struct kdp_ip aligned_ip
, *ip
= &aligned_ip
;
629 struct kdp_ether_header
*eh
;
632 kdp_panic("kdp_send: no input packet");
635 /* Packet size cannot be larger than the static space allocated for it. */
636 if (pkt
.len
> KDP_MAXPACKET
) {
637 kdp_panic("kdp_send: packet too large (%d > %u)", pkt
.len
, KDP_MAXPACKET
);
640 pkt
.off
-= (unsigned int)sizeof(struct kdp_udpiphdr
);
643 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
645 ui
= (struct kdp_udpiphdr
*)&pkt
.data
[pkt
.off
];
647 ui
->ui_next
= ui
->ui_prev
= 0;
649 ui
->ui_pr
= IPPROTO_UDP
;
650 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof(struct kdp_udphdr
));
651 ui
->ui_src
= adr
.loc
.in
;
652 ui
->ui_dst
= adr
.rmt
.in
;
653 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
654 ui
->ui_dport
= remote_port
;
655 ui
->ui_ulen
= ui
->ui_len
;
658 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
659 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
661 ip
= (struct kdp_ip
*)&pkt
.data
[pkt
.off
];
663 ip
->ip_len
= htons((ushort_t
)(sizeof(struct kdp_udpiphdr
) + pkt
.len
));
664 ip
->ip_v
= IPVERSION
;
665 ip
->ip_id
= htons(ip_id
++);
666 ip
->ip_hl
= sizeof(struct kdp_ip
) >> 2;
667 ip
->ip_ttl
= udp_ttl
;
669 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
671 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
674 pkt
.len
+= (unsigned int)sizeof(struct kdp_udpiphdr
);
676 pkt
.off
-= (unsigned int)sizeof(struct kdp_ether_header
);
678 eh
= (struct kdp_ether_header
*)&pkt
.data
[pkt
.off
];
679 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
680 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
681 eh
->ether_type
= htons(ETHERTYPE_IP
);
683 pkt
.len
+= (unsigned int)sizeof(struct kdp_ether_header
);
684 kdp_send_data(&pkt
.data
[pkt
.off
], pkt
.len
);
689 debugger_if_necessary(void)
691 if ((current_debugger
== KDP_CUR_DB
) && halt_in_debugger
) {
693 halt_in_debugger
= 0;
698 /* We don't interpret this pointer, we just give it to the bsd stack
699 * so it can decide when to set the MAC and IP info. We'll
700 * early initialize the MAC/IP info if we can so that we can use
701 * KDP early in boot. These values may subsequently get over-written
702 * when the interface gets initialized for real.
705 kdp_set_interface(void *ifp
, const struct kdp_ether_addr
*macaddr
)
708 struct kdp_in_addr addr
= { .s_addr
= 0 };
711 kdp_current_ifp
= ifp
;
713 if (PE_parse_boot_argn("kdp_ip_addr", kdpstr
, sizeof(kdpstr
))) {
714 /* look for a static ip address */
715 if (inet_aton(kdpstr
, &addr
) == FALSE
) {
722 /* use saved ip address */
723 save_ip_in_nvram
= TRUE
;
725 len
= sizeof(kdpstr
);
726 if (PEReadNVRAMProperty("_kdp_ipstr", kdpstr
, &len
) == FALSE
) {
730 kdpstr
[len
< sizeof(kdpstr
) ? len
: sizeof(kdpstr
) - 1] = '\0';
731 if (inet_aton(kdpstr
, &addr
) == FALSE
) {
736 kdp_current_ip_address
= addr
.s_addr
;
738 kdp_current_mac_address
= *macaddr
;
741 /* we can't drop into the debugger at this point because the
742 * link will likely not be up. when getDebuggerLinkStatus() support gets
743 * added to the appropriate network drivers, adding the
744 * following will enable this capability:
745 * debugger_if_necessary();
752 kdp_get_interface(void)
754 return kdp_current_ifp
;
758 kdp_set_ip_and_mac_addresses(
759 struct kdp_in_addr
*ipaddr
,
760 struct kdp_ether_addr
*macaddr
)
762 static uint64_t last_time
= (uint64_t) -1;
763 static uint64_t throttle_val
= 0;
767 if (kdp_current_ip_address
== ipaddr
->s_addr
) {
771 /* don't replace if serial debugging is configured */
772 if (!KDP_SERIAL_ENABLED() ||
773 (kdp_current_ip_address
!= KDP_SERIAL_IPADDR
)) {
774 kdp_current_mac_address
= *macaddr
;
775 kdp_current_ip_address
= ipaddr
->s_addr
;
778 if (save_ip_in_nvram
== FALSE
) {
782 if (inet_ntoa_r(*ipaddr
, addr
, sizeof(addr
)) == NULL
) {
786 /* throttle writes if needed */
788 nanoseconds_to_absolutetime(KDP_THROTTLE_VALUE
, &throttle_val
);
791 cur_time
= mach_absolute_time();
792 if (last_time
== (uint64_t) -1 ||
793 ((cur_time
- last_time
) > throttle_val
)) {
794 PEWriteNVRAMProperty("_kdp_ipstr", addr
,
795 (const unsigned int) strlen(addr
));
797 last_time
= cur_time
;
800 debugger_if_necessary();
804 kdp_set_gateway_mac(void *gatewaymac
)
806 router_mac
= *(struct kdp_ether_addr
*)gatewaymac
;
807 flag_router_mac_initialized
= TRUE
;
810 struct kdp_ether_addr
811 kdp_get_mac_addr(void)
813 return kdp_current_mac_address
;
817 kdp_get_ip_address(void)
819 return (unsigned int)kdp_current_ip_address
;
823 kdp_disable_arp(void)
825 kdp_flag
&= ~(DB_ARP
);
829 kdp_arp_dispatch(void)
831 struct kdp_ether_arp aligned_ea
, *ea
= &aligned_ea
;
832 unsigned arp_header_offset
;
834 arp_header_offset
= (unsigned)sizeof(struct kdp_ether_header
) + pkt
.off
;
835 memcpy((void *)ea
, (void *)&pkt
.data
[arp_header_offset
], sizeof(*ea
));
837 switch (ntohs(ea
->arp_op
)) {
842 kdp_process_arp_reply(ea
);
850 kdp_process_arp_reply(struct kdp_ether_arp
*ea
)
852 /* Are we interested in ARP replies? */
853 if (flag_arp_resolved
== TRUE
) {
857 /* Did we receive a reply from the right source? */
858 if (((struct kdp_in_addr
*)(ea
->arp_spa
))->s_addr
!= target_ip
) {
862 flag_arp_resolved
= TRUE
;
863 current_resolved_MAC
= *(struct kdp_ether_addr
*) (ea
->arp_sha
);
868 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
873 kdp_arp_reply(struct kdp_ether_arp
*ea
)
875 struct kdp_ether_header
*eh
;
877 struct kdp_in_addr isaddr
, itaddr
, myaddr
;
878 struct kdp_ether_addr my_enaddr
;
880 eh
= (struct kdp_ether_header
*)&pkt
.data
[pkt
.off
];
881 pkt
.off
+= (unsigned int)sizeof(struct kdp_ether_header
);
883 if (ntohs(ea
->arp_op
) != ARPOP_REQUEST
) {
887 myaddr
.s_addr
= kdp_get_ip_address();
888 my_enaddr
= kdp_get_mac_addr();
890 if ((ntohl(myaddr
.s_addr
) == 0) ||
891 ((my_enaddr
.ether_addr_octet
[0] & 0xff) == 0
892 && (my_enaddr
.ether_addr_octet
[1] & 0xff) == 0
893 && (my_enaddr
.ether_addr_octet
[2] & 0xff) == 0
894 && (my_enaddr
.ether_addr_octet
[3] & 0xff) == 0
895 && (my_enaddr
.ether_addr_octet
[4] & 0xff) == 0
896 && (my_enaddr
.ether_addr_octet
[5] & 0xff) == 0
901 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof(isaddr
));
902 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof(itaddr
));
904 if (itaddr
.s_addr
== myaddr
.s_addr
) {
905 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
906 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
908 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
909 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
911 ea
->arp_op
= htons(ARPOP_REPLY
);
912 ea
->arp_pro
= htons(ETHERTYPE_IP
);
913 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
914 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
915 eh
->ether_type
= htons(ETHERTYPE_ARP
);
916 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
917 pkt
.off
-= (unsigned int)sizeof(struct kdp_ether_header
);
918 /* pkt.len is still the length we want, ether_header+ether_arp */
919 kdp_send_data(&pkt
.data
[pkt
.off
], pkt
.len
);
926 struct kdp_ether_header
*eh
= NULL
;
927 struct kdp_udpiphdr aligned_ui
, *ui
= &aligned_ui
;
928 struct kdp_ip aligned_ip
, *ip
= &aligned_ip
;
929 static int msg_printed
;
932 kdp_panic("kdp_poll");
935 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
936 if (msg_printed
== 0) {
938 printf("kdp_poll: no debugger device\n");
943 pkt
.off
= pkt
.len
= 0;
944 kdp_receive_data(pkt
.data
, &pkt
.len
, 3 /* ms */);
950 if (pkt
.len
>= sizeof(struct kdp_ether_header
)) {
951 eh
= (struct kdp_ether_header
*)&pkt
.data
[pkt
.off
];
953 if (kdp_flag
& KDP_ARP
) {
954 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
) {
961 if (pkt
.len
< (sizeof(struct kdp_ether_header
) + sizeof(struct kdp_udpiphdr
))) {
965 pkt
.off
+= (unsigned int)sizeof(struct kdp_ether_header
);
966 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
971 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
972 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
974 ui
= (struct kdp_udpiphdr
*)&pkt
.data
[pkt
.off
];
975 ip
= (struct kdp_ip
*)&pkt
.data
[pkt
.off
];
978 pkt
.off
+= (unsigned int)sizeof(struct kdp_udpiphdr
);
979 if (ui
->ui_pr
!= IPPROTO_UDP
) {
983 if (ip
->ip_hl
> (sizeof(struct kdp_ip
) >> 2)) {
987 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
988 if (panicd_port
== (ntohs(ui
->ui_dport
)) &&
989 flag_panic_dump_in_progress
) {
990 last_panic_port
= ui
->ui_sport
;
995 /* If we receive a kernel debugging packet whilst a
996 * core dump is in progress, abort the transfer and
997 * enter the debugger if not told otherwise.
999 else if (flag_panic_dump_in_progress
) {
1000 if (!flag_dont_abort_panic_dump
) {
1001 abort_panic_transfer();
1006 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
1007 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
1008 adr
.loc
.in
= ui
->ui_dst
;
1010 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
1011 adr
.rmt
.in
= ui
->ui_src
;
1015 * Calculate kdp packet length.
1017 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - (unsigned int)sizeof(struct kdp_udphdr
);
1022 /* Create and transmit an ARP resolution request for the target IP address.
1023 * This is modeled on ether_inet_arp()/RFC 826.
1027 transmit_ARP_request(uint32_t ip_addr
)
1029 struct kdp_ether_header
*eh
= (struct kdp_ether_header
*) &pkt
.data
[0];
1030 struct kdp_ether_arp
*ea
= (struct kdp_ether_arp
*) &pkt
.data
[sizeof(struct kdp_ether_header
)];
1032 KDP_DEBUG("Transmitting ARP request\n");
1033 /* Populate the ether_header */
1034 eh
->ether_type
= htons(ETHERTYPE_ARP
);
1035 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
1036 enaddr_copy(ðerbroadcastaddr
, eh
->ether_dhost
);
1038 /* Populate the ARP header */
1039 ea
->arp_pro
= htons(ETHERTYPE_IP
);
1040 ea
->arp_hln
= sizeof(ea
->arp_sha
);
1041 ea
->arp_pln
= sizeof(ea
->arp_spa
);
1042 ea
->arp_hrd
= htons(ARPHRD_ETHER
);
1043 ea
->arp_op
= htons(ARPOP_REQUEST
);
1046 enaddr_copy(ðerbroadcastaddr
, ea
->arp_tha
);
1047 memcpy(ea
->arp_tpa
, (void *) &ip_addr
, sizeof(ip_addr
));
1050 enaddr_copy(&kdp_current_mac_address
, ea
->arp_sha
);
1051 memcpy(ea
->arp_spa
, (void *) &kdp_current_ip_address
, sizeof(kdp_current_ip_address
));
1054 pkt
.len
= sizeof(struct kdp_ether_header
) + sizeof(struct kdp_ether_arp
);
1056 kdp_send_data(&pkt
.data
[pkt
.off
], pkt
.len
);
1060 kdp_arp_resolve(uint32_t arp_target_ip
, struct kdp_ether_addr
*resolved_MAC
)
1062 int poll_count
= 256; /* ~770 ms modulo broadcast/delayed traffic? */
1065 #define NUM_ARP_TX_RETRIES 5
1067 target_ip
= arp_target_ip
;
1068 flag_arp_resolved
= FALSE
;
1071 pkt
.off
= pkt
.len
= 0;
1075 if (tretries
>= NUM_ARP_TX_RETRIES
) {
1079 KDP_DEBUG("ARP TX attempt #%d \n", tretries
);
1081 transmit_ARP_request(arp_target_ip
);
1083 while (!pkt
.input
&& !flag_arp_resolved
&& flag_panic_dump_in_progress
&& --poll_count
) {
1087 if (flag_arp_resolved
) {
1088 *resolved_MAC
= current_resolved_MAC
;
1092 if (!flag_panic_dump_in_progress
|| pkt
.input
) { /* we received a debugging packet, bail*/
1093 printf("Received a debugger packet,transferring control to debugger\n");
1094 /* Indicate that we should wait in the debugger when we return */
1095 kdp_flag
|= DBG_POST_CORE
;
1098 } else { /* We timed out */
1099 if (0 == poll_count
) {
1101 goto TRANSMIT_RETRY
;
1112 unsigned short reply_port
;
1113 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
1115 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
1118 while (!pkt
.input
) {
1123 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
1125 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
1128 // ignore replies -- we're not expecting them anyway.
1129 if (hdr
->is_reply
) {
1133 if (hdr
->request
== KDP_REATTACH
) {
1134 exception_seq
= hdr
->seq
;
1137 // check for retransmitted request
1138 if (hdr
->seq
== (exception_seq
- 1)) {
1139 /* retransmit last reply */
1140 kdp_send_data(&saved_reply
.data
[saved_reply
.off
],
1143 } else if ((hdr
->seq
!= exception_seq
) &&
1144 (hdr
->request
!= KDP_CONNECT
)) {
1145 printf("kdp: bad sequence %d (want %d)\n",
1146 hdr
->seq
, exception_seq
);
1150 /* This is a manual side-channel to the main KDP protocol.
1151 * A client like GDB/kgmacros can manually construct
1152 * a request, set the input flag, issue a dummy KDP request,
1153 * and then manually collect the result
1155 if (manual_pkt
.input
) {
1156 kdp_hdr_t
*manual_hdr
= (kdp_hdr_t
*)&manual_pkt
.data
;
1157 unsigned short manual_port_unused
= 0;
1158 if (!manual_hdr
->is_reply
) {
1160 int packet_length
= manual_pkt
.len
;
1161 kdp_packet((unsigned char *)&manual_pkt
.data
,
1163 &manual_port_unused
);
1164 manual_pkt
.len
= packet_length
;
1166 manual_pkt
.input
= 0;
1169 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
1171 (unsigned short *)&reply_port
)) {
1172 boolean_t sideband
= FALSE
;
1174 /* if it's an already connected error message,
1175 * send a sideband reply for that. for successful connects,
1176 * make sure the sequence number is correct. */
1177 if (hdr
->request
== KDP_CONNECT
) {
1178 kdp_connect_reply_t
*rp
=
1179 (kdp_connect_reply_t
*) &pkt
.data
[pkt
.off
];
1180 kdp_error_t err
= rp
->error
;
1182 if (err
== KDPERR_NO_ERROR
) {
1183 exception_seq
= hdr
->seq
;
1184 } else if (err
== KDPERR_ALREADY_CONNECTED
) {
1189 kdp_reply(reply_port
, sideband
);
1194 } while (kdp
.is_halted
);
1198 kdp_connection_wait(void)
1200 unsigned short reply_port
;
1201 struct kdp_ether_addr kdp_mac_addr
= kdp_get_mac_addr();
1202 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
1205 * Do both a printf() and a kprintf() of the MAC and IP so that
1206 * they will print out on headless machines but not be added to
1210 if (KDP_SERIAL_ENABLED()) {
1211 printf("Using serial KDP.\n");
1212 kprintf("Using serial KDP.\n");
1214 printf("ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1215 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
1216 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
1217 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
1218 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
1219 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
1220 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
1222 kprintf("ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1223 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
1224 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
1225 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
1226 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
1227 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
1228 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
1230 printf("ip address: %d.%d.%d.%d\n",
1231 (ip_addr
& 0xff000000) >> 24,
1232 (ip_addr
& 0xff0000) >> 16,
1233 (ip_addr
& 0xff00) >> 8,
1236 kprintf("ip address: %d.%d.%d.%d\n",
1237 (ip_addr
& 0xff000000) >> 24,
1238 (ip_addr
& 0xff0000) >> 16,
1239 (ip_addr
& 0xff00) >> 8,
1243 printf("\nWaiting for remote debugger connection.\n");
1244 kprintf("\nWaiting for remote debugger connection.\n");
1246 if (reattach_wait
== 0) {
1247 if ((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc())) {
1248 printf("Options..... Type\n");
1249 printf("------------ ----\n");
1250 printf("continue.... 'c'\n");
1251 printf("reboot...... 'r'\n");
1260 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
1262 while (!pkt
.input
) {
1263 if (kdp_flag
& KDP_GETC_ENA
) {
1264 switch (kdp_getc()) {
1266 printf("Continuing...\n");
1269 printf("Rebooting...\n");
1270 kdp_machine_reboot();
1280 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
1282 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
1284 if (hdr
->request
== KDP_HOSTREBOOT
) {
1285 kdp_machine_reboot();
1286 /* should not return! */
1288 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
1289 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
1290 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
1292 (unsigned short *)&reply_port
)) {
1293 kdp_reply(reply_port
, FALSE
);
1295 if (hdr
->request
== KDP_REATTACH
) {
1297 hdr
->request
= KDP_DISCONNECT
;
1303 } while (!kdp
.is_conn
);
1305 if (current_debugger
== KDP_CUR_DB
) {
1306 active_debugger
= 1;
1308 printf("Connected to remote debugger.\n");
1309 kprintf("Connected to remote debugger.\n");
1314 unsigned int exception
,
1316 unsigned int subcode
1319 unsigned short remote_port
;
1320 unsigned int timeout_count
= 100;
1321 unsigned int poll_timeout
;
1324 pkt
.off
= sizeof(struct kdp_ether_header
) + sizeof(struct kdp_udpiphdr
);
1325 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
1327 (unsigned short *)&remote_port
,
1328 (unsigned int)exception
,
1330 (unsigned int)subcode
);
1332 kdp_send(remote_port
);
1335 while (!pkt
.input
&& poll_timeout
) {
1341 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
1348 if (kdp
.exception_ack_needed
) {
1349 kdp_us_spin(250000);
1351 } while (kdp
.exception_ack_needed
&& timeout_count
--);
1353 if (kdp
.exception_ack_needed
) {
1354 // give up & disconnect
1355 printf("kdp: exception ack timeout\n");
1356 if (current_debugger
== KDP_CUR_DB
) {
1357 active_debugger
= 0;
1365 unsigned int exception
,
1367 unsigned int subcode
,
1372 if (saved_state
== 0) {
1373 printf("kdp_raise_exception with NULL state\n");
1377 if (exception
!= EXC_BREAKPOINT
) {
1378 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
1381 printf("%s exception (%x,%x,%x)\n",
1382 exception_message
[index
],
1383 exception
, code
, subcode
);
1388 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1389 * do this. I think the client and the host can get out of sync.
1391 kdp
.saved_state
= saved_state
;
1392 kdp
.kdp_cpu
= cpu_number();
1393 kdp
.kdp_thread
= current_thread();
1395 if (kdp_en_setmode
) {
1396 (*kdp_en_setmode
)(TRUE
); /* enabling link mode */
1399 kdp_panic("kdp_raise_exception");
1402 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
)
1403 || (kdp_flag
& PANIC_LOG_DUMP
))
1404 && panic_active()) {
1406 if (kdp_flag
& REBOOT_POST_CORE
&& dumped_kernel_core()) {
1407 kdp_machine_reboot();
1410 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && !panic_active()
1412 disableConsoleOutput
= FALSE
;
1414 if (kdp_flag
& REBOOT_POST_CORE
&& dumped_kernel_core()) {
1415 kdp_machine_reboot();
1418 if (!(kdp_flag
& DBG_POST_CORE
)) {
1419 goto exit_debugger_loop
;
1426 kdp_connection_wait();
1428 kdp_send_exception(exception
, code
, subcode
);
1429 if (kdp
.exception_ack_needed
) {
1430 kdp
.exception_ack_needed
= FALSE
;
1431 kdp_remove_all_breakpoints();
1432 printf("Remote debugger disconnected.\n");
1437 kdp
.is_halted
= TRUE
; /* XXX */
1438 kdp_handler(saved_state
);
1440 kdp_remove_all_breakpoints();
1441 printf("Remote debugger disconnected.\n");
1444 /* Allow triggering a panic core dump when connected to the machine
1445 * Continuing after setting kdp_trigger_core_dump should do the
1449 if (1 == kdp_trigger_core_dump
) {
1450 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
1452 if (kdp_flag
& REBOOT_POST_CORE
&& dumped_kernel_core()) {
1453 kdp_machine_reboot();
1455 kdp_trigger_core_dump
= 0;
1458 /* Trigger a reboot if the user has set this flag through the
1459 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1460 * in the protocol,but that will need gdb support,and when it's
1461 * available, it should work automatically.
1463 if (1 == flag_kdp_trigger_reboot
) {
1464 kdp_machine_reboot();
1465 /* If we're still around, reset the flag */
1466 flag_kdp_trigger_reboot
= 0;
1469 if (kdp_reentry_deadline
) {
1470 kdp_schedule_debugger_reentry(kdp_reentry_deadline
);
1471 printf("Debugger re-entry scheduled in %d milliseconds\n", kdp_reentry_deadline
);
1472 kdp_reentry_deadline
= 0;
1477 #if defined(__x86_64__)
1478 /* We only support returning from KDP on x86 */
1479 if (reattach_wait
== 1)
1486 if (kdp_en_setmode
) {
1487 (*kdp_en_setmode
)(FALSE
); /* link cleanup */
1494 kdp
.reply_port
= kdp
.exception_port
= 0;
1495 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
1496 kdp
.exception_seq
= kdp
.conn_seq
= 0;
1497 kdp
.session_key
= 0;
1498 pkt
.input
= manual_pkt
.input
= FALSE
;
1499 pkt
.len
= pkt
.off
= manual_pkt
.len
= 0;
1503 create_panic_header(unsigned int request
, const char *corename
,
1504 unsigned length
, unsigned int block
)
1506 struct kdp_udpiphdr aligned_ui
, *ui
= &aligned_ui
;
1507 struct kdp_ip aligned_ip
, *ip
= &aligned_ip
;
1508 struct kdp_ether_header
*eh
;
1509 struct corehdr
*coreh
;
1510 const char *mode
= "octet";
1511 size_t modelen
= strlen(mode
) + 1;
1513 size_t fmask_size
= sizeof(KDP_FEATURE_MASK_STRING
) + sizeof(kdp_crashdump_feature_mask
);
1515 pkt
.off
= sizeof(struct kdp_ether_header
);
1516 pkt
.len
= (unsigned int)(length
+ ((request
== KDP_WRQ
) ? modelen
+ fmask_size
: 0) +
1517 (corename
? (strlen(corename
) + 1): 0) + sizeof(struct corehdr
));
1520 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
1522 ui
= (struct kdp_udpiphdr
*)&pkt
.data
[pkt
.off
];
1524 ui
->ui_next
= ui
->ui_prev
= 0;
1526 ui
->ui_pr
= IPPROTO_UDP
;
1527 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof(struct kdp_udphdr
));
1528 ui
->ui_src
.s_addr
= (uint32_t)kdp_current_ip_address
;
1529 /* Already in network byte order via inet_aton() */
1530 ui
->ui_dst
.s_addr
= panic_server_ip
;
1531 ui
->ui_sport
= htons(panicd_port
);
1532 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(panicd_port
) : last_panic_port
);
1533 ui
->ui_ulen
= ui
->ui_len
;
1536 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
1537 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
1539 ip
= (struct kdp_ip
*)&pkt
.data
[pkt
.off
];
1541 ip
->ip_len
= htons((ushort_t
)(sizeof(struct kdp_udpiphdr
) + pkt
.len
));
1542 ip
->ip_v
= IPVERSION
;
1543 ip
->ip_id
= htons(ip_id
++);
1544 ip
->ip_hl
= sizeof(struct kdp_ip
) >> 2;
1545 ip
->ip_ttl
= udp_ttl
;
1547 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
1549 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
1552 pkt
.len
+= (unsigned int)sizeof(struct kdp_udpiphdr
);
1554 pkt
.off
+= (unsigned int)sizeof(struct kdp_udpiphdr
);
1556 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1557 coreh
->th_opcode
= htons((u_short
)request
);
1559 if (request
== KDP_WRQ
) {
1560 char *cp
= coreh
->th_u
.tu_rpl
;
1561 /* Calculate available string space (remaining space after accounting for mandatory components). */
1562 size_t length_remaining
= (sizeof(pkt
.data
) - pkt
.off
- offsetof(struct corehdr
, th_u
)
1563 - sizeof(kdp_crashdump_feature_mask
) - sizeof(kdp_crashdump_pkt_size
));
1565 /* account for the extra NULL characters that have been added historically */
1566 int len
= snprintf(cp
, length_remaining
, "%s%c%s%c%s", corename
, '\0', mode
, '\0', KDP_FEATURE_MASK_STRING
);
1568 kdb_printf("Unable to create core header packet.\n");
1570 } else if (len
>= length_remaining
) {
1571 kdb_printf("dumpinfo does not fit into KDP packet.\n");
1576 /* Append feature flags. The value is already converted with htonl in startup code. */
1577 bcopy(&kdp_crashdump_feature_mask
, cp
, sizeof(kdp_crashdump_feature_mask
));
1578 cp
+= sizeof(kdp_crashdump_feature_mask
);
1580 /* Override default packet size from boot arguments (if present). */
1581 kdp_crashdump_pkt_size
= KDP_LARGE_CRASHDUMP_PKT_SIZE
;
1582 if (PE_parse_boot_argn("kdp_crashdump_pkt_size", &kdp_crashdump_pkt_size
, sizeof(kdp_crashdump_pkt_size
)) &&
1583 (kdp_crashdump_pkt_size
> KDP_LARGE_CRASHDUMP_PKT_SIZE
)) {
1584 kdp_crashdump_pkt_size
= KDP_LARGE_CRASHDUMP_PKT_SIZE
;
1585 kdb_printf("kdp_crashdump_pkt_size is too large. Reverting to %d\n", kdp_crashdump_pkt_size
);
1588 uint32_t pktsz
= htonl(kdp_crashdump_pkt_size
);
1589 bcopy(&pktsz
, cp
, sizeof(uint32_t));
1591 coreh
->th_block
= htonl((unsigned int) block
);
1594 pkt
.off
-= (unsigned int)sizeof(struct kdp_udpiphdr
);
1595 pkt
.off
-= (unsigned int)sizeof(struct kdp_ether_header
);
1597 eh
= (struct kdp_ether_header
*)&pkt
.data
[pkt
.off
];
1598 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
1599 enaddr_copy(&destination_mac
, eh
->ether_dhost
);
1600 eh
->ether_type
= htons(ETHERTYPE_IP
);
1602 pkt
.len
+= (unsigned int)sizeof(struct kdp_ether_header
);
1607 kdp_send_crashdump_seek(char *corename
, uint64_t seek_off
)
1611 if (kdp_feature_large_crashdumps
) {
1612 panic_error
= kdp_send_crashdump_pkt(KDP_SEEK
, corename
,
1616 uint32_t off
= (uint32_t) seek_off
;
1617 panic_error
= kdp_send_crashdump_pkt(KDP_SEEK
, corename
,
1621 if (panic_error
< 0) {
1622 printf("kdp_send_crashdump_pkt failed with error %d\n",
1627 return KERN_SUCCESS
;
1631 kdp_send_crashdump_data(unsigned int request
, char *corename
,
1632 uint64_t length
, void * txstart
)
1634 int panic_error
= 0;
1636 while ((length
> 0) || !txstart
) {
1637 uint64_t chunk
= MIN(kdp_crashdump_pkt_size
, length
);
1639 panic_error
= kdp_send_crashdump_pkt(request
, corename
, chunk
,
1641 if (panic_error
< 0) {
1642 printf("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1648 txstart
= (void *)(((uintptr_t) txstart
) + chunk
);
1651 return KERN_SUCCESS
;
1654 uint32_t kdp_crashdump_short_pkt
;
1657 kdp_send_crashdump_pkt(unsigned int request
, char *corename
,
1658 uint64_t length
, void *panic_data
)
1661 struct corehdr
*th
= NULL
;
1662 char rretries
, tretries
;
1664 if (kdp_dump_start_time
== 0) {
1665 kdp_dump_start_time
= mach_absolute_time();
1666 kdp_superblock_dump_start_time
= kdp_dump_start_time
;
1669 tretries
= rretries
= 0;
1670 poll_count
= KDP_CRASHDUMP_POLL_COUNT
;
1671 pkt
.off
= pkt
.len
= 0;
1672 if (request
== KDP_WRQ
) { /* longer timeout for initial request */
1679 if (tretries
>= 15) {
1680 /* The crashdump server is unreachable for some reason. This could be a network
1681 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1682 * which is a long standing problem with the IOKit polled mode network driver
1683 * shim which can prevent transmits/receives completely.
1685 printf("Cannot contact panic server, timing out.\n");
1690 printf("TX retry #%d ", tretries
);
1693 th
= create_panic_header(request
, corename
, (unsigned)length
, panic_block
);
1695 printf("Unable to get panic header.\n");
1699 if (request
== KDP_DATA
) {
1700 /* as all packets are kdp_crashdump_pkt_size in length, the last packet
1701 * may end up with trailing bits. make sure that those
1702 * bits aren't confusing. */
1703 if (length
< kdp_crashdump_pkt_size
) {
1704 kdp_crashdump_short_pkt
++;
1705 memset(th
->th_data
+ length
, 'Y',
1706 kdp_crashdump_pkt_size
- (uint32_t) length
);
1709 if (!kdp_machine_vm_read((mach_vm_address_t
)(uintptr_t)panic_data
, (caddr_t
) th
->th_data
, length
)) {
1710 uintptr_t next_page
= round_page((uintptr_t)panic_data
);
1711 memset((caddr_t
) th
->th_data
, 'X', (size_t)length
);
1712 if ((next_page
- ((uintptr_t) panic_data
)) < length
) {
1713 uint64_t resid
= length
- (next_page
- (intptr_t) panic_data
);
1714 if (!kdp_machine_vm_read((mach_vm_address_t
)(uintptr_t)next_page
, (caddr_t
) th
->th_data
+ (length
- resid
), resid
)) {
1715 memset((caddr_t
) th
->th_data
+ (length
- resid
), 'X', (size_t)resid
);
1719 } else if (request
== KDP_SEEK
) {
1720 if (kdp_feature_large_crashdumps
) {
1721 *(uint64_t *) th
->th_data
= OSSwapHostToBigInt64((*(uint64_t *) panic_data
));
1723 *(unsigned int *) th
->th_data
= htonl(*(unsigned int *) panic_data
);
1727 kdp_send_data(&pkt
.data
[pkt
.off
], pkt
.len
);
1729 /* Listen for the ACK */
1731 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1739 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1740 if (request
== KDP_WRQ
) {
1741 uint16_t opcode64
= ntohs(th
->th_opcode
);
1742 uint16_t features64
= (opcode64
& 0xFF00) >> 8;
1743 if ((opcode64
& 0xFF) == KDP_ACK
) {
1744 kdp_feature_large_crashdumps
= features64
& KDP_FEATURE_LARGE_CRASHDUMPS
;
1745 if (features64
& KDP_FEATURE_LARGE_PKT_SIZE
) {
1746 kdp_feature_large_pkt_size
= 1;
1748 kdp_feature_large_pkt_size
= 0;
1749 kdp_crashdump_pkt_size
= 512;
1751 printf("Protocol features: 0x%x\n", (uint32_t) features64
);
1752 th
->th_opcode
= htons(KDP_ACK
);
1755 if (ntohs(th
->th_opcode
) == KDP_ACK
&& ntohl(th
->th_block
) == panic_block
) {
1757 if (ntohs(th
->th_opcode
) == KDP_ERROR
) {
1758 printf("Panic server returned error %d, retrying\n", ntohl(th
->th_code
));
1760 goto TRANSMIT_RETRY
;
1761 } else if (ntohl(th
->th_block
) == (panic_block
- 1)) {
1762 printf("RX retry ");
1763 if (++rretries
> 1) {
1764 goto TRANSMIT_RETRY
;
1770 } else if (!flag_panic_dump_in_progress
) { /* we received a debugging packet, bail*/
1771 printf("Received a debugger packet,transferring control to debugger\n");
1772 /* Configure that if not set ..*/
1773 kdp_flag
|= DBG_POST_CORE
;
1775 } else { /* We timed out */
1776 if (0 == poll_count
) {
1778 kdp_us_spin((tretries
% 4) * panic_timeout
); /* capped linear backoff */
1779 goto TRANSMIT_RETRY
;
1783 if (!(++panic_block
% SBLOCKSZ
)) {
1785 kdb_printf_unbuffered(".");
1786 ctime
= mach_absolute_time();
1787 kdp_superblock_dump_time
= ctime
- kdp_superblock_dump_start_time
;
1788 kdp_superblock_dump_start_time
= ctime
;
1789 if (kdp_superblock_dump_time
> kdp_max_superblock_dump_time
) {
1790 kdp_max_superblock_dump_time
= kdp_superblock_dump_time
;
1792 if (kdp_superblock_dump_time
< kdp_min_superblock_dump_time
) {
1793 kdp_min_superblock_dump_time
= kdp_superblock_dump_time
;
1797 if (request
== KDP_EOF
) {
1798 printf("\nTotal number of packets transmitted: %d\n", panic_block
);
1799 printf("Avg. superblock transfer abstime 0x%llx\n", ((mach_absolute_time() - kdp_dump_start_time
) / panic_block
) * SBLOCKSZ
);
1800 printf("Minimum superblock transfer abstime: 0x%llx\n", kdp_min_superblock_dump_time
);
1801 printf("Maximum superblock transfer abstime: 0x%llx\n", kdp_max_superblock_dump_time
);
1803 return KERN_SUCCESS
;
1809 return (c
> 47) && (c
< 58);
1812 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1813 * would be to have the integrator run a script which would copy the
1814 * xnu version into a string or an int somewhere at project submission
1815 * time - makes assumptions about sizeof(version), but will not fail if
1816 * it changes, but may be incorrect.
1818 /* 2006: Incorporated a change from Darwin user P. Lovell to extract
1819 * the minor kernel version numbers from the version string.
1822 kdp_get_xnu_version(char *versionbuf
)
1824 const char *versionpos
;
1828 size_t length_remaining
= (sizeof(pkt
.data
) - pkt
.off
);
1830 strlcpy(vstr
, "custom", 10);
1831 if (kdp_machine_vm_read((mach_vm_address_t
)(uintptr_t)version
, versionbuf
, 128)) {
1832 versionbuf
[127] = '\0';
1833 versionpos
= strnstr(versionbuf
, "xnu-", 115);
1835 strncpy(vstr
, versionpos
, sizeof(vstr
));
1836 vstr
[sizeof(vstr
) - 1] = '\0';
1837 vptr
= vstr
+ 4; /* Begin after "xnu-" */
1838 while (*vptr
&& (isdigit(*vptr
) || *vptr
== '.')) {
1842 /* Remove trailing period, if any */
1843 if (*(--vptr
) == '.') {
1849 strlcpy(versionbuf
, vstr
, length_remaining
);
1854 kdp_set_dump_info(const uint32_t flags
, const char *filename
,
1855 const char *destipstr
, const char *routeripstr
,
1856 const uint32_t port
)
1860 if (destipstr
&& (destipstr
[0] != '\0')) {
1861 strlcpy(panicd_ip_str
, destipstr
, sizeof(panicd_ip_str
));
1862 panicd_specified
= 1;
1865 if (routeripstr
&& (routeripstr
[0] != '\0')) {
1866 strlcpy(router_ip_str
, routeripstr
, sizeof(router_ip_str
));
1867 router_specified
= 1;
1870 if (filename
&& (filename
[0] != '\0')) {
1871 strlcpy(corename_str
, filename
, sizeof(corename_str
));
1872 corename_specified
= TRUE
;
1874 corename_specified
= FALSE
;
1877 /* Accept only valid UDP port numbers. */
1878 if (port
&& port
<= USHRT_MAX
) {
1879 panicd_port
= (unsigned short)port
;
1881 kdb_printf("kdp_set_dump_info: Skipping invalid panicd port %d (using %d)\n", port
, panicd_port
);
1884 /* on a disconnect, should we stay in KDP or not? */
1885 noresume_on_disconnect
= (flags
& KDP_DUMPINFO_NORESUME
) ? 1 : 0;
1887 if ((flags
& KDP_DUMPINFO_DUMP
) == 0) {
1891 /* the rest of the commands can modify kdp_flags */
1892 cmd
= flags
& KDP_DUMPINFO_MASK
;
1893 if (cmd
== KDP_DUMPINFO_DISABLE
) {
1894 kdp_flag
&= ~KDP_PANIC_DUMP_ENABLED
;
1895 panicd_specified
= 0;
1896 kdp_trigger_core_dump
= 0;
1900 kdp_flag
&= ~REBOOT_POST_CORE
;
1901 if (flags
& KDP_DUMPINFO_REBOOT
) {
1902 kdp_flag
|= REBOOT_POST_CORE
;
1905 kdp_flag
&= ~PANIC_LOG_DUMP
;
1906 if (cmd
== KDP_DUMPINFO_PANICLOG
) {
1907 kdp_flag
|= PANIC_LOG_DUMP
;
1910 kdp_flag
&= ~SYSTEM_LOG_DUMP
;
1911 if (cmd
== KDP_DUMPINFO_SYSTEMLOG
) {
1912 kdp_flag
|= SYSTEM_LOG_DUMP
;
1915 /* trigger a dump */
1916 kdp_flag
|= DBG_POST_CORE
;
1918 flag_dont_abort_panic_dump
= (flags
& KDP_DUMPINFO_NOINTR
) ?
1922 disableConsoleOutput
= 0;
1923 kdp_trigger_core_dump
= 1;
1927 kdp_get_dump_info(kdp_dumpinfo_reply_t
*rp
)
1929 if (panicd_specified
) {
1930 strlcpy(rp
->destip
, panicd_ip_str
,
1931 sizeof(rp
->destip
));
1933 rp
->destip
[0] = '\0';
1936 if (router_specified
) {
1937 strlcpy(rp
->routerip
, router_ip_str
,
1938 sizeof(rp
->routerip
));
1940 rp
->routerip
[0] = '\0';
1943 if (corename_specified
) {
1944 strlcpy(rp
->name
, corename_str
,
1950 rp
->port
= panicd_port
;
1953 if (!panicd_specified
) {
1954 rp
->type
|= KDP_DUMPINFO_DISABLE
;
1955 } else if (kdp_flag
& PANIC_LOG_DUMP
) {
1956 rp
->type
|= KDP_DUMPINFO_PANICLOG
;
1958 rp
->type
|= KDP_DUMPINFO_CORE
;
1961 if (noresume_on_disconnect
) {
1962 rp
->type
|= KDP_DUMPINFO_NORESUME
;
1967 /* Primary dispatch routine for the system dump */
1969 kdp_panic_dump(void)
1971 char coreprefix
[10];
1976 uint32_t current_ip
= ntohl((uint32_t)kdp_current_ip_address
);
1978 if (flag_panic_dump_in_progress
) {
1979 kdb_printf("System dump aborted.\n");
1980 goto panic_dump_exit
;
1983 printf("Entering system dump routine\n");
1985 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
1986 kdb_printf("Error: No transport device registered for kernel crashdump\n");
1990 if (!panicd_specified
) {
1991 kdb_printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
1992 goto panic_dump_exit
;
1995 flag_panic_dump_in_progress
= TRUE
;
1998 kdp_panic("kdp_panic_dump: unexpected pending input packet");
2001 kdp_get_xnu_version((char *) &pkt
.data
[0]);
2003 if (!corename_specified
) {
2005 /* Panic log bit takes precedence over core dump bit */
2006 if ((debugger_panic_str
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
2007 strlcpy(coreprefix
, "paniclog", sizeof(coreprefix
));
2008 } else if (kdp_flag
& SYSTEM_LOG_DUMP
) {
2009 strlcpy(coreprefix
, "systemlog", sizeof(coreprefix
));
2011 strlcpy(coreprefix
, "core", sizeof(coreprefix
));
2012 if (!kdp_corezip_disabled
) {
2013 strlcpy(coresuffix
, ".gz", sizeof(coresuffix
));
2017 abstime
= mach_absolute_time();
2018 pkt
.data
[20] = '\0';
2019 snprintf(corename_str
,
2020 sizeof(corename_str
),
2021 "%s-%s-%d.%d.%d.%d-%x%s",
2022 coreprefix
, &pkt
.data
[0],
2023 (current_ip
& 0xff000000) >> 24,
2024 (current_ip
& 0xff0000) >> 16,
2025 (current_ip
& 0xff00) >> 8,
2026 (current_ip
& 0xff),
2027 (unsigned int) (abstime
& 0xffffffff),
2031 if (0 == inet_aton(panicd_ip_str
, (struct kdp_in_addr
*) &panic_server_ip
)) {
2032 kdb_printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str
);
2034 kdb_printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str
, panicd_port
);
2037 destination_mac
= router_mac
;
2039 if (kdp_arp_resolve(panic_server_ip
, &temp_mac
)) {
2040 kdb_printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str
);
2041 destination_mac
= temp_mac
;
2043 if (!flag_panic_dump_in_progress
) {
2044 goto panic_dump_exit
;
2046 if (router_specified
) {
2047 if (0 == inet_aton(router_ip_str
, (struct kdp_in_addr
*) &parsed_router_ip
)) {
2048 kdb_printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str
);
2050 router_ip
= parsed_router_ip
;
2051 if (kdp_arp_resolve(router_ip
, &temp_mac
)) {
2052 destination_mac
= temp_mac
;
2053 kdb_printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
2059 if (!flag_panic_dump_in_progress
) {
2060 goto panic_dump_exit
;
2063 kdb_printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
2064 destination_mac
.ether_addr_octet
[0] & 0xff,
2065 destination_mac
.ether_addr_octet
[1] & 0xff,
2066 destination_mac
.ether_addr_octet
[2] & 0xff,
2067 destination_mac
.ether_addr_octet
[3] & 0xff,
2068 destination_mac
.ether_addr_octet
[4] & 0xff,
2069 destination_mac
.ether_addr_octet
[5] & 0xff);
2071 kdb_printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
2072 kdb_printf("Sending write request for %s\n", corename_str
);
2074 if ((panic_error
= kdp_send_crashdump_pkt(KDP_WRQ
, corename_str
, 0, NULL
)) < 0) {
2075 kdb_printf("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
2076 goto panic_dump_exit
;
2079 /* Just the panic log requested */
2080 if ((debugger_panic_str
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
2081 kdb_printf_unbuffered("Transmitting panic log, please wait: ");
2082 kdp_send_crashdump_data(KDP_DATA
, corename_str
,
2083 debug_buf_ptr
- debug_buf_base
,
2085 kdp_send_crashdump_pkt(KDP_EOF
, NULL
, 0, ((void *) 0));
2086 printf("Please file a bug report on this panic, if possible.\n");
2087 goto panic_dump_exit
;
2090 /* maybe we wanted the systemlog */
2091 if (kdp_flag
& SYSTEM_LOG_DUMP
) {
2092 long start_off
= msgbufp
->msg_bufx
;
2095 kdb_printf_unbuffered("Transmitting system log, please wait: ");
2096 if (start_off
>= msgbufp
->msg_bufr
) {
2097 len
= msgbufp
->msg_size
- start_off
;
2098 kdp_send_crashdump_data(KDP_DATA
, corename_str
, len
,
2099 msgbufp
->msg_bufc
+ start_off
);
2100 /* seek to remove trailing bytes */
2101 kdp_send_crashdump_seek(corename_str
, len
);
2105 if (start_off
!= msgbufp
->msg_bufr
) {
2106 len
= msgbufp
->msg_bufr
- start_off
;
2107 kdp_send_crashdump_data(KDP_DATA
, corename_str
, len
,
2108 msgbufp
->msg_bufc
+ start_off
);
2111 kdp_send_crashdump_pkt(KDP_EOF
, NULL
, 0, ((void *) 0));
2112 goto panic_dump_exit
;
2115 /* We want a core dump if we're here */
2116 kern_dump(KERN_DUMP_NET
);
2119 abort_panic_transfer();
2125 begin_panic_transfer(void)
2127 flag_panic_dump_in_progress
= TRUE
;
2131 abort_panic_transfer(void)
2133 flag_panic_dump_in_progress
= FALSE
;
2134 flag_dont_abort_panic_dump
= FALSE
;
2138 #if CONFIG_SERIAL_KDP
2140 static boolean_t needs_serial_init
= TRUE
;
2143 kdp_serial_send(void *rpkt
, unsigned int rpkt_len
)
2146 kdp_serialize_packet((unsigned char *)rpkt
, rpkt_len
, pal_serial_putc_nocr
);
2150 kdp_serial_receive(void *rpkt
, unsigned int *rpkt_len
, unsigned int timeout
)
2153 uint64_t now
, deadline
;
2155 clock_interval_to_deadline(timeout
, 1000 * 1000 /* milliseconds */, &deadline
);
2158 for (clock_get_uptime(&now
); now
< deadline
; clock_get_uptime(&now
)) {
2159 readkar
= pal_serial_getc();
2161 unsigned char *packet
;
2162 // printf("got char %02x\n", readkar);
2163 if ((packet
= kdp_unserialize_packet((unsigned char)readkar
, rpkt_len
))) {
2164 memcpy(rpkt
, packet
, *rpkt_len
);
2173 kdp_serial_setmode(boolean_t active
)
2175 if (active
== FALSE
) { /* leaving KDP */
2179 if (!needs_serial_init
) {
2184 needs_serial_init
= FALSE
;
2190 kdp_serial_callout(__unused
void *arg
, kdp_event_t event
)
2193 * When we stop KDP, set the bit to re-initialize the console serial
2194 * port the next time we send/receive a KDP packet. We don't do it on
2195 * KDP_EVENT_ENTER directly because it also gets called when we trap to
2196 * KDP for non-external debugging, i.e., stackshot or core dumps.
2198 * Set needs_serial_init on exit (and initialization, see above) and not
2199 * enter because enter is sent multiple times and causes excess
2204 case KDP_EVENT_PANICLOG
:
2205 case KDP_EVENT_ENTER
:
2207 case KDP_EVENT_EXIT
:
2208 needs_serial_init
= TRUE
;
2213 #endif /* CONFIG_SERIAL_KDP */
2218 strlcpy(kdp_kernelversion_string
, version
, sizeof(kdp_kernelversion_string
));
2220 /* Relies on platform layer calling panic_init() before kdp_init() */
2221 assert(startup_phase
>= STARTUP_SUB_TUNABLES
);
2222 if (kernel_uuid_string
[0] != '\0') {
2224 * Update kdp_kernelversion_string with our UUID
2225 * generated at link time.
2228 strlcat(kdp_kernelversion_string
, "; UUID=", sizeof(kdp_kernelversion_string
));
2229 strlcat(kdp_kernelversion_string
, kernel_uuid_string
, sizeof(kdp_kernelversion_string
));
2234 #if defined(__x86_64__) || defined(__arm__) || defined(__arm64__)
2235 if (vm_kernel_slide
) {
2236 char KASLR_stext
[19];
2237 strlcat(kdp_kernelversion_string
, "; stext=", sizeof(kdp_kernelversion_string
));
2238 snprintf(KASLR_stext
, sizeof(KASLR_stext
), "%p", (void *) vm_kernel_stext
);
2239 strlcat(kdp_kernelversion_string
, KASLR_stext
, sizeof(kdp_kernelversion_string
));
2243 if (debug_boot_arg
& DB_REBOOT_POST_CORE
) {
2244 kdp_flag
|= REBOOT_POST_CORE
;
2246 #if defined(__x86_64__)
2250 kdp_timer_callout_init();
2251 kdp_crashdump_feature_mask
= htonl(kdp_crashdump_feature_mask
);
2254 #if CONFIG_SERIAL_KDP
2256 struct kdp_in_addr ipaddr
;
2257 struct kdp_ether_addr macaddr
;
2259 boolean_t kdp_match_name_found
= PE_parse_boot_argn("kdp_match_name", kdpname
, sizeof(kdpname
));
2260 boolean_t kdp_not_serial
= kdp_match_name_found
? (strncmp(kdpname
, "serial", sizeof(kdpname
))) : TRUE
;
2262 #if defined(__arm__) || defined(__arm64__)
2263 //respect any custom debugger boot-args
2264 if (kdp_match_name_found
&& kdp_not_serial
) {
2267 #else /* defined(__arm__) || defined(__arm64__) */
2268 // serial must be explicitly requested
2269 if (!kdp_match_name_found
|| kdp_not_serial
) {
2272 #endif /* defined(__arm__) || defined(__arm64__) */
2274 #if defined(__arm__) || defined(__arm64__)
2275 if (kdp_not_serial
&& PE_consistent_debug_enabled() && debug_boot_arg
) {
2278 printf("Serial requested, consistent debug disabled or debug boot arg not present, configuring debugging over serial\n");
2280 #endif /* defined(__arm__) || defined(__arm64__) */
2282 kprintf("Initializing serial KDP\n");
2284 kdp_register_callout(kdp_serial_callout
, NULL
);
2285 kdp_register_link(NULL
, kdp_serial_setmode
);
2286 kdp_register_send_receive(kdp_serial_send
, kdp_serial_receive
);
2288 /* fake up an ip and mac for early serial debugging */
2289 macaddr
.ether_addr_octet
[0] = 's';
2290 macaddr
.ether_addr_octet
[1] = 'e';
2291 macaddr
.ether_addr_octet
[2] = 'r';
2292 macaddr
.ether_addr_octet
[3] = 'i';
2293 macaddr
.ether_addr_octet
[4] = 'a';
2294 macaddr
.ether_addr_octet
[5] = 'l';
2295 ipaddr
.s_addr
= KDP_SERIAL_IPADDR
;
2296 kdp_set_ip_and_mac_addresses(&ipaddr
, &macaddr
);
2298 #endif /* CONFIG_SERIAL_KDP */
2301 #else /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2306 #endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2308 #if !(MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING)
2309 static struct kdp_ether_addr kdp_current_mac_address
= {.ether_addr_octet
= {0, 0, 0, 0, 0, 0}};
2311 /* XXX ugly forward declares to stop warnings */
2312 void *kdp_get_interface(void);
2313 void kdp_set_ip_and_mac_addresses(struct kdp_in_addr
*, struct kdp_ether_addr
*);
2314 void kdp_set_gateway_mac(void *);
2315 void kdp_set_interface(void *);
2316 void kdp_register_send_receive(void *, void *);
2317 void kdp_unregister_send_receive(void *, void *);
2319 uint32_t kdp_stack_snapshot_bytes_traced(void);
2322 kdp_register_send_receive(__unused
void *send
, __unused
void *receive
)
2327 kdp_unregister_send_receive(__unused
void *send
, __unused
void *receive
)
2332 kdp_get_interface( void)
2338 kdp_get_ip_address(void )
2343 struct kdp_ether_addr
2344 kdp_get_mac_addr(void)
2346 return kdp_current_mac_address
;
2350 kdp_set_ip_and_mac_addresses(
2351 __unused
struct kdp_in_addr
*ipaddr
,
2352 __unused
struct kdp_ether_addr
*macaddr
)
2357 kdp_set_gateway_mac(__unused
void *gatewaymac
)
2362 kdp_set_interface(__unused
void *ifp
)
2367 kdp_register_link(__unused kdp_link_t link
, __unused kdp_mode_t mode
)
2372 kdp_unregister_link(__unused kdp_link_t link
, __unused kdp_mode_t mode
)
2376 #endif /* !(MACH_KDP && CONFIG_KDP_INTERACTIVE_DEBUGGING) */
2378 #if !CONFIG_KDP_INTERACTIVE_DEBUGGING
2379 extern __attribute__((noreturn
)) void panic_spin_forever(void);
2381 __attribute__((noreturn
))
2383 kdp_raise_exception(
2384 __unused
unsigned int exception
,
2385 __unused
unsigned int code
,
2386 __unused
unsigned int subcode
,
2387 __unused
void *saved_state
2391 kdp_raise_exception(
2392 unsigned int exception
,
2394 unsigned int subcode
,
2399 #if defined(__arm__) || defined(__arm64__)
2400 assert(kernel_debugging_allowed());
2403 #if CONFIG_KDP_INTERACTIVE_DEBUGGING
2404 kdp_debugger_loop(exception
, code
, subcode
, saved_state
);
2405 #else /* CONFIG_KDP_INTERACTIVE_DEBUGGING */
2407 assert(current_debugger
!= KDP_CUR_DB
);
2408 panic_spin_forever();
2409 #endif /* CONFIG_KDP_INTERACTIVE_DEBUGGING */