2 * Copyright (c) 2000-2008 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.
39 #include <mach/boolean.h>
40 #include <mach/mach_types.h>
41 #include <mach/exception_types.h>
42 #include <kern/cpu_data.h>
43 #include <kern/debug.h>
44 #include <kern/clock.h>
46 #include <kdp/kdp_core.h>
47 #include <kdp/kdp_internal.h>
48 #include <kdp/kdp_en_debugger.h>
49 #include <kdp/kdp_callout.h>
50 #include <kdp/kdp_udp.h>
52 #include <kdp/kdp_serial.h>
55 #include <vm/vm_map.h>
56 #include <vm/vm_protos.h>
57 #include <vm/vm_kern.h> /* kernel_map */
59 #include <mach/memory_object_types.h>
61 #include <sys/msgbuf.h>
65 #define DO_ALIGN 1 /* align all packet data accesses */
67 extern int kdp_getc(void);
68 extern int reattach_wait
;
70 extern int serial_getc(void);
71 extern void serial_putc(char);
72 extern int serial_init(void);
74 static u_short ip_id
; /* ip packet ctr, for ids */
76 /* @(#)udp_usrreq.c 2.2 88/05/23 4.0NFSSRC SMI; from UCB 7.1 6/5/86 */
79 * UDP protocol implementation.
80 * Per RFC 768, August, 1980.
82 #define UDP_TTL 60 /* deflt time to live for UDP packets */
83 int udp_ttl
= UDP_TTL
;
84 static unsigned char exception_seq
;
87 unsigned char data
[KDP_MAXPACKET
];
88 unsigned int off
, len
;
92 struct kdp_manual_pkt manual_pkt
;
101 struct ether_addr ea
;
106 *exception_message
[] = {
108 "Memory access", /* EXC_BAD_ACCESS */
109 "Failed instruction", /* EXC_BAD_INSTRUCTION */
110 "Arithmetic", /* EXC_ARITHMETIC */
111 "Emulation", /* EXC_EMULATION */
112 "Software", /* EXC_SOFTWARE */
113 "Breakpoint" /* EXC_BREAKPOINT */
116 volatile int kdp_flag
= 0;
118 static kdp_send_t kdp_en_send_pkt
;
119 static kdp_receive_t kdp_en_recv_pkt
;
122 static uint32_t kdp_current_ip_address
= 0;
123 static struct ether_addr kdp_current_mac_address
= {{0, 0, 0, 0, 0, 0}};
124 static void *kdp_current_ifp
;
126 static void kdp_handler( void *);
128 static uint32_t panic_server_ip
= 0;
129 static uint32_t parsed_router_ip
= 0;
130 static uint32_t router_ip
= 0;
131 static uint32_t target_ip
= 0;
133 static volatile boolean_t panicd_specified
= FALSE
;
134 static boolean_t router_specified
= FALSE
;
135 static boolean_t corename_specified
= FALSE
;
136 static unsigned int panicd_port
= CORE_REMOTE_PORT
;
138 static struct ether_addr etherbroadcastaddr
= {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
140 static struct ether_addr router_mac
= {{0, 0, 0 , 0, 0, 0}};
141 static struct ether_addr destination_mac
= {{0, 0, 0 , 0, 0, 0}};
142 static struct ether_addr temp_mac
= {{0, 0, 0 , 0, 0, 0}};
143 static struct ether_addr current_resolved_MAC
= {{0, 0, 0 , 0, 0, 0}};
145 static boolean_t flag_panic_dump_in_progress
= FALSE
;
146 static boolean_t flag_router_mac_initialized
= FALSE
;
147 static boolean_t flag_dont_abort_panic_dump
= FALSE
;
149 static boolean_t flag_arp_resolved
= FALSE
;
151 static unsigned int panic_timeout
= 100000;
152 static unsigned int last_panic_port
= CORE_REMOTE_PORT
;
154 unsigned int SEGSIZE
= 512;
156 static char panicd_ip_str
[20];
157 static char router_ip_str
[20];
158 static char corename_str
[50];
160 static unsigned int panic_block
= 0;
161 volatile unsigned int kdp_trigger_core_dump
= 0;
162 __private_extern__
volatile unsigned int flag_kdp_trigger_reboot
= 0;
164 extern unsigned int not_in_kdp
;
166 extern unsigned int disableConsoleOutput
;
168 extern void kdp_call(void);
169 extern boolean_t
kdp_call_kdb(void);
170 extern int kern_dump(void);
172 void * kdp_get_interface(void);
173 void kdp_set_gateway_mac(void *);
174 void kdp_set_ip_and_mac_addresses(struct in_addr
*, struct ether_addr
*);
175 void kdp_set_interface(void *);
177 void kdp_disable_arp(void);
178 static void kdp_arp_reply(struct ether_arp
*);
179 static void kdp_process_arp_reply(struct ether_arp
*);
180 static boolean_t
kdp_arp_resolve(uint32_t, struct ether_addr
*);
182 static volatile unsigned kdp_reentry_deadline
;
183 #if defined(__LP64__)
184 uint32_t kdp_crashdump_feature_mask
= KDP_FEATURE_LARGE_CRASHDUMPS
;
185 static uint32_t kdp_feature_large_crashdumps
;
188 static boolean_t gKDPDebug
= FALSE
;
189 #define KDP_DEBUG(...) if (gKDPDebug) printf(__VA_ARGS__);
191 int kdp_snapshot
= 0;
192 static int stack_snapshot_ret
= 0;
193 static unsigned stack_snapshot_bytes_traced
= 0;
195 static void *stack_snapshot_buf
;
196 static uint32_t stack_snapshot_bufsize
;
197 static int stack_snapshot_pid
;
198 static uint32_t stack_snapshot_flags
;
199 static uint32_t stack_snapshot_dispatch_offset
;
201 static unsigned int old_debugger
;
204 kdp_snapshot_preflight(int pid
, void * tracebuf
, uint32_t tracebuf_size
,
205 uint32_t flags
, uint32_t dispatch_offset
);
208 kdp_snapshot_postflight(void);
211 kdp_stackshot(int pid
, void *tracebuf
, uint32_t tracebuf_size
,
212 uint32_t flags
, uint32_t dispatch_offset
, uint32_t *pbytesTraced
);
215 kdp_stack_snapshot_geterror(void);
218 kdp_stack_snapshot_bytes_traced(void);
224 kdp_ml_enter_debugger_wrapper(__unused
void *param0
, __unused
void *param1
) {
225 kdp_ml_enter_debugger();
229 kdp_timer_callout_init(void) {
230 kdp_timer_call
= thread_call_allocate(kdp_ml_enter_debugger_wrapper
, NULL
);
235 kdp_register_send_receive(
237 kdp_receive_t receive
)
239 unsigned int debug
= 0;
243 kdp_timer_callout_init();
245 PE_parse_boot_argn("debug", &debug
, sizeof (debug
));
246 #if defined(__LP64__)
247 kdp_crashdump_feature_mask
= htonl(kdp_crashdump_feature_mask
);
253 kdp_en_send_pkt
= send
;
254 kdp_en_recv_pkt
= receive
;
256 if (debug
& DB_KDP_BP_DIS
)
257 kdp_flag
|= KDP_BP_DIS
;
258 if (debug
& DB_KDP_GETC_ENA
)
259 kdp_flag
|= KDP_GETC_ENA
;
263 if (debug
& DB_KERN_DUMP_ON_PANIC
)
264 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
265 if (debug
& DB_KERN_DUMP_ON_NMI
)
266 kdp_flag
|= PANIC_CORE_ON_NMI
;
268 if (debug
& DB_DBG_POST_CORE
)
269 kdp_flag
|= DBG_POST_CORE
;
271 if (debug
& DB_PANICLOG_DUMP
)
272 kdp_flag
|= PANIC_LOG_DUMP
;
274 if (PE_parse_boot_argn("_panicd_ip", panicd_ip_str
, sizeof (panicd_ip_str
)))
275 panicd_specified
= TRUE
;
277 if ((debug
& DB_REBOOT_POST_CORE
) && (panicd_specified
== TRUE
))
278 kdp_flag
|= REBOOT_POST_CORE
;
280 if (PE_parse_boot_argn("_router_ip", router_ip_str
, sizeof (router_ip_str
)))
281 router_specified
= TRUE
;
283 if (!PE_parse_boot_argn("panicd_port", &panicd_port
, sizeof (panicd_port
)))
284 panicd_port
= CORE_REMOTE_PORT
;
286 if (PE_parse_boot_argn("_panicd_corename", &corename_str
, sizeof (corename_str
)))
287 corename_specified
= TRUE
;
289 kdp_flag
|= KDP_READY
;
290 if (current_debugger
== NO_CUR_DB
)
291 current_debugger
= KDP_CUR_DB
;
292 if ((kdp_current_ip_address
!= 0) && halt_in_debugger
) {
299 kdp_unregister_send_receive(
300 __unused kdp_send_t send
,
301 __unused kdp_receive_t receive
)
303 if (current_debugger
== KDP_CUR_DB
)
304 current_debugger
= NO_CUR_DB
;
305 kdp_flag
&= ~KDP_READY
;
306 kdp_en_send_pkt
= NULL
;
307 kdp_en_recv_pkt
= NULL
;
310 /* Cache stack snapshot parameters in preparation for a trace */
312 kdp_snapshot_preflight(int pid
, void * tracebuf
, uint32_t tracebuf_size
, uint32_t flags
, uint32_t dispatch_offset
)
314 stack_snapshot_pid
= pid
;
315 stack_snapshot_buf
= tracebuf
;
316 stack_snapshot_bufsize
= tracebuf_size
;
317 stack_snapshot_flags
= flags
;
318 stack_snapshot_dispatch_offset
= dispatch_offset
;
320 /* Mark this debugger as active, since the polled mode driver that
321 * ordinarily does this may not be enabled (yet), or since KDB may be
322 * the primary debugger.
324 old_debugger
= current_debugger
;
325 if (old_debugger
!= KDP_CUR_DB
) {
326 current_debugger
= KDP_CUR_DB
;
331 kdp_snapshot_postflight(void)
334 if ((kdp_en_send_pkt
== NULL
) || (old_debugger
== KDB_CUR_DB
))
335 current_debugger
= old_debugger
;
339 kdp_stack_snapshot_geterror(void)
341 return stack_snapshot_ret
;
345 kdp_stack_snapshot_bytes_traced(void)
347 return stack_snapshot_bytes_traced
;
351 kdp_schedule_debugger_reentry(unsigned interval
) {
354 clock_interval_to_deadline(interval
, 1000 * 1000, &deadline
);
355 thread_call_enter_delayed(kdp_timer_call
, deadline
);
364 bcopy((char *)src
, (char *)dst
, sizeof (struct ether_addr
));
367 static unsigned short
373 unsigned int high
, low
, sum
;
383 sum
= (high
<< 8) + low
;
384 sum
= (sum
>> 16) + (sum
& 65535);
386 return (sum
> 65535 ? sum
- 65535 : sum
);
391 unsigned short reply_port
,
392 const boolean_t sideband
395 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
396 struct ip aligned_ip
, *ip
= &aligned_ip
;
397 struct in_addr tmp_ipaddr
;
398 struct ether_addr tmp_enaddr
;
399 struct ether_header
*eh
= NULL
;
402 kdp_panic("kdp_reply");
404 pkt
.off
-= (unsigned int)sizeof (struct udpiphdr
);
407 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
409 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
411 ui
->ui_next
= ui
->ui_prev
= 0;
413 ui
->ui_pr
= IPPROTO_UDP
;
414 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
415 tmp_ipaddr
= ui
->ui_src
;
416 ui
->ui_src
= ui
->ui_dst
;
417 ui
->ui_dst
= tmp_ipaddr
;
418 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
419 ui
->ui_dport
= reply_port
;
420 ui
->ui_ulen
= ui
->ui_len
;
423 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
424 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
426 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
428 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
429 ip
->ip_v
= IPVERSION
;
430 ip
->ip_id
= htons(ip_id
++);
431 ip
->ip_hl
= sizeof (struct ip
) >> 2;
432 ip
->ip_ttl
= udp_ttl
;
434 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
436 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
439 pkt
.len
+= (unsigned int)sizeof (struct udpiphdr
);
441 pkt
.off
-= (unsigned int)sizeof (struct ether_header
);
443 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
444 enaddr_copy(eh
->ether_shost
, &tmp_enaddr
);
445 enaddr_copy(eh
->ether_dhost
, eh
->ether_shost
);
446 enaddr_copy(&tmp_enaddr
, eh
->ether_dhost
);
447 eh
->ether_type
= htons(ETHERTYPE_IP
);
449 pkt
.len
+= (unsigned int)sizeof (struct ether_header
);
451 // save reply for possible retransmission
453 bcopy((char *)&pkt
, (char *)&saved_reply
, sizeof(pkt
));
455 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
457 // increment expected sequence number
464 unsigned short remote_port
467 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
468 struct ip aligned_ip
, *ip
= &aligned_ip
;
469 struct ether_header
*eh
;
472 kdp_panic("kdp_send");
474 pkt
.off
-= (unsigned int)sizeof (struct udpiphdr
);
477 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
479 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
481 ui
->ui_next
= ui
->ui_prev
= 0;
483 ui
->ui_pr
= IPPROTO_UDP
;
484 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
485 ui
->ui_src
= adr
.loc
.in
;
486 ui
->ui_dst
= adr
.rmt
.in
;
487 ui
->ui_sport
= htons(KDP_REMOTE_PORT
);
488 ui
->ui_dport
= remote_port
;
489 ui
->ui_ulen
= ui
->ui_len
;
492 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
493 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
495 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
497 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
498 ip
->ip_v
= IPVERSION
;
499 ip
->ip_id
= htons(ip_id
++);
500 ip
->ip_hl
= sizeof (struct ip
) >> 2;
501 ip
->ip_ttl
= udp_ttl
;
503 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
505 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
508 pkt
.len
+= (unsigned int)sizeof (struct udpiphdr
);
510 pkt
.off
-= (unsigned int)sizeof (struct ether_header
);
512 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
513 enaddr_copy(&adr
.loc
.ea
, eh
->ether_shost
);
514 enaddr_copy(&adr
.rmt
.ea
, eh
->ether_dhost
);
515 eh
->ether_type
= htons(ETHERTYPE_IP
);
517 pkt
.len
+= (unsigned int)sizeof (struct ether_header
);
518 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
521 /* We don't interpret this pointer, we just give it to the
522 bsd stack so it can decide when to set the MAC and IP info. */
524 kdp_set_interface(void *ifp
)
526 kdp_current_ifp
= ifp
;
530 kdp_get_interface(void)
532 return kdp_current_ifp
;
536 kdp_set_ip_and_mac_addresses(
537 struct in_addr
*ipaddr
,
538 struct ether_addr
*macaddr
)
540 kdp_current_ip_address
= ipaddr
->s_addr
;
541 kdp_current_mac_address
= *macaddr
;
542 if ((current_debugger
== KDP_CUR_DB
) && halt_in_debugger
) {
549 kdp_set_gateway_mac(void *gatewaymac
)
551 router_mac
= *(struct ether_addr
*)gatewaymac
;
552 flag_router_mac_initialized
= TRUE
;
556 kdp_get_mac_addr(void)
558 return kdp_current_mac_address
;
562 kdp_get_ip_address(void)
564 return (unsigned int)kdp_current_ip_address
;
568 kdp_disable_arp(void)
570 kdp_flag
&= ~(DB_ARP
);
574 kdp_arp_dispatch(void)
576 struct ether_arp aligned_ea
, *ea
= &aligned_ea
;
577 unsigned arp_header_offset
;
579 arp_header_offset
= (unsigned)sizeof(struct ether_header
) + pkt
.off
;
580 memcpy((void *)ea
, (void *)&pkt
.data
[arp_header_offset
], sizeof(*ea
));
582 switch(ntohs(ea
->arp_op
)) {
587 kdp_process_arp_reply(ea
);
595 kdp_process_arp_reply(struct ether_arp
*ea
)
597 /* Are we interested in ARP replies? */
598 if (flag_arp_resolved
== TRUE
)
601 /* Did we receive a reply from the right source? */
602 if (((struct in_addr
*)(ea
->arp_spa
))->s_addr
!= target_ip
)
605 flag_arp_resolved
= TRUE
;
606 current_resolved_MAC
= *(struct ether_addr
*) (ea
->arp_sha
);
611 /* ARP responses are enabled when the DB_ARP bit of the debug boot arg
616 kdp_arp_reply(struct ether_arp
*ea
)
618 struct ether_header
*eh
;
620 struct in_addr isaddr
, itaddr
, myaddr
;
621 struct ether_addr my_enaddr
;
623 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
624 pkt
.off
+= (unsigned int)sizeof(struct ether_header
);
626 if(ntohs(ea
->arp_op
) != ARPOP_REQUEST
)
629 myaddr
.s_addr
= kdp_get_ip_address();
630 my_enaddr
= kdp_get_mac_addr();
632 if ((ntohl(myaddr
.s_addr
) == 0) ||
633 ((my_enaddr
.ether_addr_octet
[0] & 0xff) == 0
634 && (my_enaddr
.ether_addr_octet
[1] & 0xff) == 0
635 && (my_enaddr
.ether_addr_octet
[2] & 0xff) == 0
636 && (my_enaddr
.ether_addr_octet
[3] & 0xff) == 0
637 && (my_enaddr
.ether_addr_octet
[4] & 0xff) == 0
638 && (my_enaddr
.ether_addr_octet
[5] & 0xff) == 0
642 (void)memcpy((void *)&isaddr
, (void *)ea
->arp_spa
, sizeof (isaddr
));
643 (void)memcpy((void *)&itaddr
, (void *)ea
->arp_tpa
, sizeof (itaddr
));
645 if (itaddr
.s_addr
== myaddr
.s_addr
) {
646 (void)memcpy((void *)ea
->arp_tha
, (void *)ea
->arp_sha
, sizeof(ea
->arp_sha
));
647 (void)memcpy((void *)ea
->arp_sha
, (void *)&my_enaddr
, sizeof(ea
->arp_sha
));
649 (void)memcpy((void *)ea
->arp_tpa
, (void *) ea
->arp_spa
, sizeof(ea
->arp_spa
));
650 (void)memcpy((void *)ea
->arp_spa
, (void *) &itaddr
, sizeof(ea
->arp_spa
));
652 ea
->arp_op
= htons(ARPOP_REPLY
);
653 ea
->arp_pro
= htons(ETHERTYPE_IP
);
654 (void)memcpy(eh
->ether_dhost
, ea
->arp_tha
, sizeof(eh
->ether_dhost
));
655 (void)memcpy(eh
->ether_shost
, &my_enaddr
, sizeof(eh
->ether_shost
));
656 eh
->ether_type
= htons(ETHERTYPE_ARP
);
657 (void)memcpy(&pkt
.data
[pkt
.off
], ea
, sizeof(*ea
));
658 pkt
.off
-= (unsigned int)sizeof (struct ether_header
);
659 /* pkt.len is still the length we want, ether_header+ether_arp */
660 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
667 struct ether_header
*eh
= NULL
;
668 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
669 struct ip aligned_ip
, *ip
= &aligned_ip
;
670 static int msg_printed
;
673 kdp_panic("kdp_poll");
675 if (!kdp_en_recv_pkt
|| !kdp_en_send_pkt
) {
676 if( msg_printed
== 0) {
678 printf("kdp_poll: no debugger device\n");
683 pkt
.off
= pkt
.len
= 0;
684 (*kdp_en_recv_pkt
)(pkt
.data
, &pkt
.len
, 3/* ms */);
689 if (pkt
.len
>= sizeof(struct ether_header
))
691 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
693 if (kdp_flag
& KDP_ARP
)
695 if (ntohs(eh
->ether_type
) == ETHERTYPE_ARP
)
703 if (pkt
.len
< (sizeof (struct ether_header
) + sizeof (struct udpiphdr
)))
706 pkt
.off
+= (unsigned int)sizeof (struct ether_header
);
707 if (ntohs(eh
->ether_type
) != ETHERTYPE_IP
) {
712 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
713 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
715 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
716 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
719 pkt
.off
+= (unsigned int)sizeof (struct udpiphdr
);
720 if (ui
->ui_pr
!= IPPROTO_UDP
) {
724 if (ip
->ip_hl
> (sizeof (struct ip
) >> 2)) {
728 if (ntohs(ui
->ui_dport
) != KDP_REMOTE_PORT
) {
729 if (panicd_port
== (ntohs(ui
->ui_dport
)) &&
730 flag_panic_dump_in_progress
) {
731 last_panic_port
= ui
->ui_sport
;
736 /* If we receive a kernel debugging packet whilst a
737 * core dump is in progress, abort the transfer and
738 * enter the debugger if not told otherwise.
741 if (flag_panic_dump_in_progress
)
743 if (!flag_dont_abort_panic_dump
) {
744 abort_panic_transfer();
749 if (!kdp
.is_conn
&& !flag_panic_dump_in_progress
) {
750 enaddr_copy(eh
->ether_dhost
, &adr
.loc
.ea
);
751 adr
.loc
.in
= ui
->ui_dst
;
753 enaddr_copy(eh
->ether_shost
, &adr
.rmt
.ea
);
754 adr
.rmt
.in
= ui
->ui_src
;
758 * Calculate kdp packet length.
760 pkt
.len
= ntohs((u_short
)ui
->ui_ulen
) - (unsigned int)sizeof (struct udphdr
);
764 /* Create and transmit an ARP resolution request for the target IP address.
765 * This is modeled on ether_inet_arp()/RFC 826.
769 transmit_ARP_request(uint32_t ip_addr
)
771 struct ether_header
*eh
= (struct ether_header
*) &pkt
.data
[0];
772 struct ether_arp
*ea
= (struct ether_arp
*) &pkt
.data
[sizeof(struct ether_header
)];
774 KDP_DEBUG("Transmitting ARP request\n");
775 /* Populate the ether_header */
776 eh
->ether_type
= htons(ETHERTYPE_ARP
);
777 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
778 enaddr_copy(ðerbroadcastaddr
, eh
->ether_dhost
);
780 /* Populate the ARP header */
781 ea
->arp_pro
= htons(ETHERTYPE_IP
);
782 ea
->arp_hln
= sizeof(ea
->arp_sha
);
783 ea
->arp_pln
= sizeof(ea
->arp_spa
);
784 ea
->arp_hrd
= htons(ARPHRD_ETHER
);
785 ea
->arp_op
= htons(ARPOP_REQUEST
);
788 enaddr_copy(ðerbroadcastaddr
, ea
->arp_tha
);
789 memcpy(ea
->arp_tpa
, (void *) &ip_addr
, sizeof(ip_addr
));
792 enaddr_copy(&kdp_current_mac_address
, ea
->arp_sha
);
793 memcpy(ea
->arp_spa
, (void *) &kdp_current_ip_address
, sizeof(kdp_current_ip_address
));
796 pkt
.len
= sizeof(struct ether_header
) + sizeof(struct ether_arp
);
798 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
802 kdp_arp_resolve(uint32_t arp_target_ip
, struct ether_addr
*resolved_MAC
)
804 int poll_count
= 256; /* ~770 ms modulo broadcast/delayed traffic? */
807 #define NUM_ARP_TX_RETRIES 5
809 target_ip
= arp_target_ip
;
810 flag_arp_resolved
= FALSE
;
813 pkt
.off
= pkt
.len
= 0;
817 if (tretries
>= NUM_ARP_TX_RETRIES
) {
821 KDP_DEBUG("ARP TX attempt #%d \n", tretries
);
823 transmit_ARP_request(arp_target_ip
);
825 while (!pkt
.input
&& !flag_arp_resolved
&& flag_panic_dump_in_progress
&& --poll_count
) {
829 if (flag_arp_resolved
) {
830 *resolved_MAC
= current_resolved_MAC
;
834 if (!flag_panic_dump_in_progress
|| pkt
.input
) /* we received a debugging packet, bail*/
836 printf("Received a debugger packet,transferring control to debugger\n");
837 /* Indicate that we should wait in the debugger when we return */
838 kdp_flag
|= DBG_POST_CORE
;
842 else /* We timed out */
843 if (0 == poll_count
) {
855 unsigned short reply_port
;
856 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
858 kdp
.saved_state
= saved_state
; // see comment in kdp_raise_exception
865 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
867 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
870 // ignore replies -- we're not expecting them anyway.
875 if (hdr
->request
== KDP_REATTACH
)
876 exception_seq
= hdr
->seq
;
878 // check for retransmitted request
879 if (hdr
->seq
== (exception_seq
- 1)) {
880 /* retransmit last reply */
881 (*kdp_en_send_pkt
)(&saved_reply
.data
[saved_reply
.off
],
884 } else if ((hdr
->seq
!= exception_seq
) &&
885 (hdr
->request
!= KDP_CONNECT
)) {
886 printf("kdp: bad sequence %d (want %d)\n",
887 hdr
->seq
, exception_seq
);
891 /* This is a manual side-channel to the main KDP protocol.
892 * A client like GDB/kgmacros can manually construct
893 * a request, set the input flag, issue a dummy KDP request,
894 * and then manually collect the result
896 if (manual_pkt
.input
) {
897 kdp_hdr_t
*manual_hdr
= (kdp_hdr_t
*)&manual_pkt
.data
;
898 unsigned short manual_port_unused
= 0;
899 if (!manual_hdr
->is_reply
) {
901 kdp_packet((unsigned char *)&manual_pkt
.data
,
902 (int *)&manual_pkt
.len
,
903 &manual_port_unused
);
905 manual_pkt
.input
= 0;
908 if (kdp_packet((unsigned char*)&pkt
.data
[pkt
.off
],
910 (unsigned short *)&reply_port
)) {
911 boolean_t sideband
= FALSE
;
913 /* if it's an already connected error message,
914 * send a sideband reply for that. for successful connects,
915 * make sure the sequence number is correct. */
916 if (hdr
->request
== KDP_CONNECT
) {
917 kdp_connect_reply_t
*rp
=
918 (kdp_connect_reply_t
*) &pkt
.data
[pkt
.off
];
919 kdp_error_t err
= rp
->error
;
921 if (err
== KDPERR_NO_ERROR
) {
922 exception_seq
= hdr
->seq
;
923 } else if (err
== KDPERR_ALREADY_CONNECTED
) {
928 kdp_reply(reply_port
, sideband
);
933 } while (kdp
.is_halted
);
937 kdp_connection_wait(void)
939 unsigned short reply_port
;
940 struct ether_addr kdp_mac_addr
= kdp_get_mac_addr();
941 unsigned int ip_addr
= ntohl(kdp_get_ip_address());
944 * Do both a printf() and a kprintf() of the MAC and IP so that
945 * they will print out on headless machines but not be added to
949 printf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
950 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
951 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
952 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
953 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
954 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
955 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
957 kprintf( "ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n",
958 kdp_mac_addr
.ether_addr_octet
[0] & 0xff,
959 kdp_mac_addr
.ether_addr_octet
[1] & 0xff,
960 kdp_mac_addr
.ether_addr_octet
[2] & 0xff,
961 kdp_mac_addr
.ether_addr_octet
[3] & 0xff,
962 kdp_mac_addr
.ether_addr_octet
[4] & 0xff,
963 kdp_mac_addr
.ether_addr_octet
[5] & 0xff);
965 printf( "ip address: %d.%d.%d.%d\n",
966 (ip_addr
& 0xff000000) >> 24,
967 (ip_addr
& 0xff0000) >> 16,
968 (ip_addr
& 0xff00) >> 8,
971 kprintf( "ip address: %d.%d.%d.%d\n",
972 (ip_addr
& 0xff000000) >> 24,
973 (ip_addr
& 0xff0000) >> 16,
974 (ip_addr
& 0xff00) >> 8,
977 printf("\nWaiting for remote debugger connection.\n");
980 if (reattach_wait
== 0) {
981 if((kdp_flag
& KDP_GETC_ENA
) && (0 != kdp_getc()))
983 printf("Options..... Type\n");
984 printf("------------ ----\n");
985 printf("continue.... 'c'\n");
986 printf("reboot...... 'r'\n");
988 printf("enter kdb... 'k'\n");
997 kdp_hdr_t aligned_hdr
, *hdr
= &aligned_hdr
;
1000 if (kdp_flag
& KDP_GETC_ENA
) {
1001 switch(kdp_getc()) {
1003 printf("Continuing...\n");
1006 printf("Rebooting...\n");
1007 kdp_machine_reboot();
1011 printf("calling kdb...\n");
1015 printf("not implemented...\n");
1025 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)hdr
, sizeof(*hdr
));
1027 hdr
= (kdp_hdr_t
*)&pkt
.data
[pkt
.off
];
1029 if (hdr
->request
== KDP_HOSTREBOOT
) {
1030 kdp_machine_reboot();
1031 /* should not return! */
1033 if (((hdr
->request
== KDP_CONNECT
) || (hdr
->request
== KDP_REATTACH
)) &&
1034 !hdr
->is_reply
&& (hdr
->seq
== exception_seq
)) {
1035 if (kdp_packet((unsigned char *)&pkt
.data
[pkt
.off
],
1037 (unsigned short *)&reply_port
))
1038 kdp_reply(reply_port
, FALSE
);
1039 if (hdr
->request
== KDP_REATTACH
) {
1041 hdr
->request
=KDP_DISCONNECT
;
1047 } while (!kdp
.is_conn
);
1049 if (current_debugger
== KDP_CUR_DB
)
1051 printf("Connected to remote debugger.\n");
1056 unsigned int exception
,
1058 unsigned int subcode
1061 unsigned short remote_port
;
1062 unsigned int timeout_count
= 100;
1063 unsigned int poll_timeout
;
1066 pkt
.off
= sizeof (struct ether_header
) + sizeof (struct udpiphdr
);
1067 kdp_exception((unsigned char *)&pkt
.data
[pkt
.off
],
1069 (unsigned short *)&remote_port
,
1070 (unsigned int)exception
,
1072 (unsigned int)subcode
);
1074 kdp_send(remote_port
);
1077 while(!pkt
.input
&& poll_timeout
)
1084 if (!kdp_exception_ack(&pkt
.data
[pkt
.off
], pkt
.len
)) {
1091 if (kdp
.exception_ack_needed
)
1092 kdp_us_spin(250000);
1094 } while (kdp
.exception_ack_needed
&& timeout_count
--);
1096 if (kdp
.exception_ack_needed
) {
1097 // give up & disconnect
1098 printf("kdp: exception ack timeout\n");
1099 if (current_debugger
== KDP_CUR_DB
)
1106 kdp_raise_exception(
1107 unsigned int exception
,
1109 unsigned int subcode
,
1115 /* Was a system trace requested ? */
1116 if (kdp_snapshot
&& (!panic_active()) && (panic_caller
== 0)) {
1117 stack_snapshot_ret
= kdp_stackshot(stack_snapshot_pid
,
1118 stack_snapshot_buf
, stack_snapshot_bufsize
,
1119 stack_snapshot_flags
, stack_snapshot_dispatch_offset
,
1120 &stack_snapshot_bytes_traced
);
1124 disable_preemption();
1126 if (saved_state
== 0)
1127 printf("kdp_raise_exception with NULL state\n");
1130 if (exception
!= EXC_BREAKPOINT
) {
1131 if (exception
> EXC_BREAKPOINT
|| exception
< EXC_BAD_ACCESS
) {
1134 printf("%s exception (%x,%x,%x)\n",
1135 exception_message
[index
],
1136 exception
, code
, subcode
);
1141 /* XXX WMG it seems that sometimes it doesn't work to let kdp_handler
1142 * do this. I think the client and the host can get out of sync.
1144 kdp
.saved_state
= saved_state
;
1145 kdp
.kdp_cpu
= cpu_number();
1146 kdp
.kdp_thread
= current_thread();
1149 kdp_panic("kdp_raise_exception");
1152 if (((kdp_flag
& KDP_PANIC_DUMP_ENABLED
) || (kdp_flag
& PANIC_LOG_DUMP
))
1153 && (panicstr
!= (char *) 0)) {
1155 if (kdp_flag
& REBOOT_POST_CORE
)
1156 kdp_machine_reboot();
1159 if ((kdp_flag
& PANIC_CORE_ON_NMI
) && (panicstr
== (char *) 0) &&
1162 disable_debug_output
= disableConsoleOutput
= FALSE
;
1165 if (!(kdp_flag
& DBG_POST_CORE
))
1166 goto exit_raise_exception
;
1171 kdp_connection_wait();
1173 kdp_send_exception(exception
, code
, subcode
);
1174 if (kdp
.exception_ack_needed
) {
1175 kdp
.exception_ack_needed
= FALSE
;
1176 kdp_remove_all_breakpoints();
1177 printf("Remote debugger disconnected.\n");
1182 kdp
.is_halted
= TRUE
; /* XXX */
1183 kdp_handler(saved_state
);
1186 kdp_remove_all_breakpoints();
1187 printf("Remote debugger disconnected.\n");
1190 /* Allow triggering a panic core dump when connected to the machine
1191 * Continuing after setting kdp_trigger_core_dump should do the
1195 if (1 == kdp_trigger_core_dump
) {
1196 kdp_flag
|= KDP_PANIC_DUMP_ENABLED
;
1198 if (kdp_flag
& REBOOT_POST_CORE
)
1199 kdp_machine_reboot();
1200 kdp_trigger_core_dump
= 0;
1203 /* Trigger a reboot if the user has set this flag through the
1204 * debugger.Ideally, this would be done through the HOSTREBOOT packet
1205 * in the protocol,but that will need gdb support,and when it's
1206 * available, it should work automatically.
1208 if (1 == flag_kdp_trigger_reboot
) {
1209 kdp_machine_reboot();
1210 /* If we're still around, reset the flag */
1211 flag_kdp_trigger_reboot
= 0;
1214 if (kdp_reentry_deadline
) {
1215 kdp_schedule_debugger_reentry(kdp_reentry_deadline
);
1216 printf("Debugger re-entry scheduled in %d milliseconds\n", kdp_reentry_deadline
);
1217 kdp_reentry_deadline
= 0;
1222 if (reattach_wait
== 1)
1225 exit_raise_exception
:
1226 enable_preemption();
1232 kdp
.reply_port
= kdp
.exception_port
= 0;
1233 kdp
.is_halted
= kdp
.is_conn
= FALSE
;
1234 kdp
.exception_seq
= kdp
.conn_seq
= 0;
1235 kdp
.session_key
= 0;
1239 create_panic_header(unsigned int request
, const char *corename
,
1240 unsigned length
, unsigned int block
)
1242 struct udpiphdr aligned_ui
, *ui
= &aligned_ui
;
1243 struct ip aligned_ip
, *ip
= &aligned_ip
;
1244 struct ether_header
*eh
;
1245 struct corehdr
*coreh
;
1246 const char *mode
= "octet";
1247 char modelen
= strlen(mode
);
1248 #if defined(__LP64__)
1249 size_t fmask_size
= sizeof(KDP_FEATURE_MASK_STRING
) + sizeof(kdp_crashdump_feature_mask
);
1251 size_t fmask_size
= 0;
1253 pkt
.off
= sizeof (struct ether_header
);
1254 pkt
.len
= (unsigned int)(length
+ ((request
== KDP_WRQ
) ? modelen
+ fmask_size
: 0) +
1255 (corename
? strlen(corename
): 0) + sizeof(struct corehdr
));
1258 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ui
, sizeof(*ui
));
1260 ui
= (struct udpiphdr
*)&pkt
.data
[pkt
.off
];
1262 ui
->ui_next
= ui
->ui_prev
= 0;
1264 ui
->ui_pr
= IPPROTO_UDP
;
1265 ui
->ui_len
= htons((u_short
)pkt
.len
+ sizeof (struct udphdr
));
1266 ui
->ui_src
.s_addr
= (uint32_t)kdp_current_ip_address
;
1267 /* Already in network byte order via inet_aton() */
1268 ui
->ui_dst
.s_addr
= panic_server_ip
;
1269 ui
->ui_sport
= htons(panicd_port
);
1270 ui
->ui_dport
= ((request
== KDP_WRQ
) ? htons(panicd_port
) : last_panic_port
);
1271 ui
->ui_ulen
= ui
->ui_len
;
1274 bcopy((char *)ui
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ui
));
1275 bcopy((char *)&pkt
.data
[pkt
.off
], (char *)ip
, sizeof(*ip
));
1277 ip
= (struct ip
*)&pkt
.data
[pkt
.off
];
1279 ip
->ip_len
= htons(sizeof (struct udpiphdr
) + pkt
.len
);
1280 ip
->ip_v
= IPVERSION
;
1281 ip
->ip_id
= htons(ip_id
++);
1282 ip
->ip_hl
= sizeof (struct ip
) >> 2;
1283 ip
->ip_ttl
= udp_ttl
;
1285 ip
->ip_sum
= htons(~ip_sum((unsigned char *)ip
, ip
->ip_hl
));
1287 bcopy((char *)ip
, (char *)&pkt
.data
[pkt
.off
], sizeof(*ip
));
1290 pkt
.len
+= (unsigned int)sizeof (struct udpiphdr
);
1292 pkt
.off
+= (unsigned int)sizeof (struct udpiphdr
);
1294 coreh
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1295 coreh
->th_opcode
= htons((u_short
)request
);
1297 if (request
== KDP_WRQ
)
1301 cp
= coreh
->th_u
.tu_rpl
;
1302 cp
+= strlcpy (cp
, corename
, KDP_MAXPACKET
);
1304 cp
+= strlcpy (cp
, mode
, KDP_MAXPACKET
- strlen(corename
));
1306 #if defined(__LP64__)
1307 cp
+= strlcpy(cp
, KDP_FEATURE_MASK_STRING
, sizeof(KDP_FEATURE_MASK_STRING
));
1308 *cp
++ = '\0'; /* Redundant */
1309 bcopy(&kdp_crashdump_feature_mask
, cp
, sizeof(kdp_crashdump_feature_mask
));
1314 coreh
->th_block
= htonl((unsigned int) block
);
1317 pkt
.off
-= (unsigned int)sizeof (struct udpiphdr
);
1318 pkt
.off
-= (unsigned int)sizeof (struct ether_header
);
1320 eh
= (struct ether_header
*)&pkt
.data
[pkt
.off
];
1321 enaddr_copy(&kdp_current_mac_address
, eh
->ether_shost
);
1322 enaddr_copy(&destination_mac
, eh
->ether_dhost
);
1323 eh
->ether_type
= htons(ETHERTYPE_IP
);
1325 pkt
.len
+= (unsigned int)sizeof (struct ether_header
);
1329 static int kdp_send_crashdump_seek(char *corename
, uint64_t seek_off
)
1333 #if defined(__LP64__)
1334 if (kdp_feature_large_crashdumps
) {
1335 panic_error
= kdp_send_crashdump_pkt(KDP_SEEK
, corename
,
1341 uint32_t off
= (uint32_t) seek_off
;
1342 panic_error
= kdp_send_crashdump_pkt(KDP_SEEK
, corename
,
1346 if (panic_error
< 0) {
1347 printf ("kdp_send_crashdump_pkt failed with error %d\n",
1355 int kdp_send_crashdump_data(unsigned int request
, char *corename
,
1356 uint64_t length
, caddr_t txstart
)
1358 int panic_error
= 0;
1360 while (length
> 0) {
1361 uint64_t chunk
= MIN(SEGSIZE
, length
);
1363 panic_error
= kdp_send_crashdump_pkt(request
, corename
, chunk
,
1365 if (panic_error
< 0) {
1366 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1370 if (!(panic_block
% 2000))
1371 kdb_printf_unbuffered(".");
1380 kdp_send_crashdump_pkt(unsigned int request
, char *corename
,
1381 uint64_t length
, void *panic_data
)
1383 struct corehdr
*th
= NULL
;
1384 int poll_count
= 2500;
1386 char rretries
= 0, tretries
= 0;
1388 pkt
.off
= pkt
.len
= 0;
1390 if (request
== KDP_WRQ
) /* longer timeout for initial request */
1396 if (tretries
>=15) {
1397 /* The crashdump server is unreachable for some reason. This could be a network
1398 * issue or, if we've been especially unfortunate, we've hit Radar 2760413,
1399 * which is a long standing problem with the IOKit polled mode network driver
1400 * shim which can prevent transmits/receives completely.
1402 printf ("Cannot contact panic server, timing out.\n");
1407 printf("TX retry #%d ", tretries
);
1409 th
= create_panic_header(request
, corename
, (unsigned)length
, panic_block
);
1411 if (request
== KDP_DATA
) {
1412 /* as all packets are SEGSIZE in length, the last packet
1413 * may end up with trailing bits. make sure that those
1414 * bits aren't confusing. */
1415 if (length
< SEGSIZE
)
1416 memset(th
->th_data
+ length
, 'X',
1417 SEGSIZE
- (uint32_t) length
);
1419 if (!kdp_machine_vm_read((mach_vm_address_t
)(intptr_t)panic_data
, (caddr_t
) th
->th_data
, length
)) {
1420 memset ((caddr_t
) th
->th_data
, 'X', (size_t)length
);
1423 else if (request
== KDP_SEEK
) {
1424 #if defined(__LP64__)
1425 if (kdp_feature_large_crashdumps
)
1426 *(uint64_t *) th
->th_data
= OSSwapHostToBigInt64((*(uint64_t *) panic_data
));
1429 *(unsigned int *) th
->th_data
= htonl(*(unsigned int *) panic_data
);
1432 (*kdp_en_send_pkt
)(&pkt
.data
[pkt
.off
], pkt
.len
);
1434 /* Listen for the ACK */
1436 while (!pkt
.input
&& flag_panic_dump_in_progress
&& poll_count
) {
1445 th
= (struct corehdr
*) &pkt
.data
[pkt
.off
];
1446 #if defined(__LP64__)
1447 if (request
== KDP_WRQ
) {
1448 uint16_t opcode64
= ntohs(th
->th_opcode
);
1449 uint16_t features64
= (opcode64
& 0xFF00)>>8;
1450 if ((opcode64
& 0xFF) == KDP_ACK
) {
1451 kdp_feature_large_crashdumps
= features64
& KDP_FEATURE_LARGE_CRASHDUMPS
;
1452 printf("Protocol features: 0x%x\n", (uint32_t) features64
);
1453 th
->th_opcode
= htons(KDP_ACK
);
1457 if (ntohs(th
->th_opcode
) == KDP_ACK
&& ntohl(th
->th_block
) == panic_block
) {
1460 if (ntohs(th
->th_opcode
) == KDP_ERROR
) {
1461 printf("Panic server returned error %d, retrying\n", ntohl(th
->th_code
));
1463 goto TRANSMIT_RETRY
;
1466 if (ntohl(th
->th_block
) == (panic_block
- 1)) {
1467 printf("RX retry ");
1469 goto TRANSMIT_RETRY
;
1475 if (!flag_panic_dump_in_progress
) /* we received a debugging packet, bail*/
1477 printf("Received a debugger packet,transferring control to debugger\n");
1478 /* Configure that if not set ..*/
1479 kdp_flag
|= DBG_POST_CORE
;
1482 else /* We timed out */
1483 if (0 == poll_count
) {
1485 kdp_us_spin ((tretries%4
) * panic_timeout
); /* capped linear backoff */
1486 goto TRANSMIT_RETRY
;
1491 if (request
== KDP_EOF
)
1492 printf("\nTotal number of packets transmitted: %d\n", panic_block
);
1500 return ((c
> 47) && (c
< 58));
1502 /* From user mode Libc - this ought to be in a library */
1504 strnstr(char *s
, const char *find
, size_t slen
)
1509 if ((c
= *find
++) != '\0') {
1513 if ((sc
= *s
++) == '\0' || slen
-- < 1)
1518 } while (strncmp(s
, find
, len
) != 0);
1524 extern char version
[];
1526 /* Horrid hack to extract xnu version if possible - a much cleaner approach
1527 * would be to have the integrator run a script which would copy the
1528 * xnu version into a string or an int somewhere at project submission
1529 * time - makes assumptions about sizeof(version), but will not fail if
1530 * it changes, but may be incorrect.
1532 /* 2006: Incorporated a change from Darwin user P. Lovell to extract
1533 * the minor kernel version numbers from the version string.
1536 kdp_get_xnu_version(char *versionbuf
)
1543 strlcpy(vstr
, "custom", 10);
1544 if (strlcpy(versionbuf
, version
, 95) < 95) {
1545 versionpos
= strnstr(versionbuf
, "xnu-", 90);
1547 strncpy(vstr
, versionpos
, sizeof(vstr
));
1548 vstr
[sizeof(vstr
)-1] = '\0';
1549 vptr
= vstr
+ 4; /* Begin after "xnu-" */
1550 while (*vptr
&& (isdigit(*vptr
) || *vptr
== '.'))
1553 /* Remove trailing period, if any */
1554 if (*(--vptr
) == '.')
1559 strlcpy(versionbuf
, vstr
, KDP_MAXPACKET
);
1563 extern char *inet_aton(const char *cp
, struct in_addr
*pin
);
1566 kdp_set_dump_info(const uint32_t flags
, const char *filename
,
1567 const char *destipstr
, const char *routeripstr
,
1568 const uint32_t port
)
1572 if (destipstr
&& (destipstr
[0] != '\0')) {
1573 strlcpy(panicd_ip_str
, destipstr
, sizeof(panicd_ip_str
));
1574 panicd_specified
= 1;
1577 if (routeripstr
&& (routeripstr
[0] != '\0')) {
1578 strlcpy(router_ip_str
, routeripstr
, sizeof(router_ip_str
));
1579 router_specified
= 1;
1582 if (filename
&& (filename
[0] != '\0')) {
1583 strlcpy(corename_str
, filename
, sizeof(corename_str
));
1584 corename_specified
= TRUE
;
1586 corename_specified
= FALSE
;
1592 /* on a disconnect, should we stay in KDP or not? */
1593 noresume_on_disconnect
= (flags
& KDP_DUMPINFO_NORESUME
) ? 1 : 0;
1595 if ((flags
& KDP_DUMPINFO_DUMP
) == 0)
1598 /* the rest of the commands can modify kdp_flags */
1599 cmd
= flags
& KDP_DUMPINFO_MASK
;
1600 if (cmd
== KDP_DUMPINFO_DISABLE
) {
1601 kdp_flag
&= ~KDP_PANIC_DUMP_ENABLED
;
1602 panicd_specified
= 0;
1603 kdp_trigger_core_dump
= 0;
1607 kdp_flag
&= ~REBOOT_POST_CORE
;
1608 if (flags
& KDP_DUMPINFO_REBOOT
)
1609 kdp_flag
|= REBOOT_POST_CORE
;
1611 kdp_flag
&= ~PANIC_LOG_DUMP
;
1612 if (cmd
== KDP_DUMPINFO_PANICLOG
)
1613 kdp_flag
|= PANIC_LOG_DUMP
;
1615 kdp_flag
&= ~SYSTEM_LOG_DUMP
;
1616 if (cmd
== KDP_DUMPINFO_SYSTEMLOG
)
1617 kdp_flag
|= SYSTEM_LOG_DUMP
;
1619 /* trigger a dump */
1620 kdp_flag
|= DBG_POST_CORE
;
1622 flag_dont_abort_panic_dump
= (flags
& KDP_DUMPINFO_NOINTR
) ?
1626 logPanicDataToScreen
= 1;
1627 disableConsoleOutput
= 0;
1628 disable_debug_output
= 0;
1629 kdp_trigger_core_dump
= 1;
1633 kdp_get_dump_info(uint32_t *flags
, char *filename
, char *destipstr
,
1634 char *routeripstr
, uint32_t *port
)
1637 if (panicd_specified
)
1638 strlcpy(destipstr
, panicd_ip_str
,
1639 sizeof(panicd_ip_str
));
1641 destipstr
[0] = '\0';
1645 if (router_specified
)
1646 strlcpy(routeripstr
, router_ip_str
,
1647 sizeof(router_ip_str
));
1649 routeripstr
[0] = '\0';
1653 if (corename_specified
)
1654 strlcpy(filename
, corename_str
,
1655 sizeof(corename_str
));
1662 *port
= panicd_port
;
1666 if (!panicd_specified
)
1667 *flags
|= KDP_DUMPINFO_DISABLE
;
1668 else if (kdp_flag
& PANIC_LOG_DUMP
)
1669 *flags
|= KDP_DUMPINFO_PANICLOG
;
1671 *flags
|= KDP_DUMPINFO_CORE
;
1673 if (noresume_on_disconnect
)
1674 *flags
|= KDP_DUMPINFO_NORESUME
;
1679 /* Primary dispatch routine for the system dump */
1681 kdp_panic_dump(void)
1683 char coreprefix
[10];
1687 uint32_t current_ip
= ntohl((uint32_t)kdp_current_ip_address
);
1689 if (flag_panic_dump_in_progress
) {
1690 printf("System dump aborted.\n");
1691 goto panic_dump_exit
;
1694 printf("Entering system dump routine\n");
1696 if (!panicd_specified
) {
1697 printf("A dump server was not specified in the boot-args, terminating kernel core dump.\n");
1698 goto panic_dump_exit
;
1701 flag_panic_dump_in_progress
= TRUE
;
1705 kdp_panic("kdp_panic_dump: unexpected pending input packet");
1707 kdp_get_xnu_version((char *) &pkt
.data
[0]);
1709 if (!corename_specified
) {
1710 /* Panic log bit takes precedence over core dump bit */
1711 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
))
1712 strlcpy(coreprefix
, "paniclog", sizeof(coreprefix
));
1713 else if (kdp_flag
& SYSTEM_LOG_DUMP
)
1714 strlcpy(coreprefix
, "systemlog", sizeof(coreprefix
));
1716 strlcpy(coreprefix
, "core", sizeof(coreprefix
));
1718 abstime
= mach_absolute_time();
1719 pkt
.data
[20] = '\0';
1720 snprintf (corename_str
, sizeof(corename_str
), "%s-%s-%d.%d.%d.%d-%x",
1721 coreprefix
, &pkt
.data
[0],
1722 (current_ip
& 0xff000000) >> 24,
1723 (current_ip
& 0xff0000) >> 16,
1724 (current_ip
& 0xff00) >> 8,
1725 (current_ip
& 0xff),
1726 (unsigned int) (abstime
& 0xffffffff));
1729 if (0 == inet_aton(panicd_ip_str
, (struct in_addr
*) &panic_server_ip
)) {
1730 printf("inet_aton() failed interpreting %s as a panic server IP\n", panicd_ip_str
);
1733 printf("Attempting connection to panic server configured at IP %s, port %d\n", panicd_ip_str
, panicd_port
);
1735 destination_mac
= router_mac
;
1737 if (kdp_arp_resolve(panic_server_ip
, &temp_mac
)) {
1738 printf("Resolved %s's (or proxy's) link level address\n", panicd_ip_str
);
1739 destination_mac
= temp_mac
;
1742 if (!flag_panic_dump_in_progress
) goto panic_dump_exit
;
1743 if (router_specified
) {
1744 if (0 == inet_aton(router_ip_str
, (struct in_addr
*) &parsed_router_ip
))
1745 printf("inet_aton() failed interpreting %s as an IP\n", router_ip_str
);
1747 router_ip
= parsed_router_ip
;
1748 if (kdp_arp_resolve(router_ip
, &temp_mac
)) {
1749 destination_mac
= temp_mac
;
1750 printf("Routing through specified router IP %s (%d)\n", router_ip_str
, router_ip
);
1756 if (!flag_panic_dump_in_progress
) goto panic_dump_exit
;
1758 printf("Transmitting packets to link level address: %02x:%02x:%02x:%02x:%02x:%02x\n",
1759 destination_mac
.ether_addr_octet
[0] & 0xff,
1760 destination_mac
.ether_addr_octet
[1] & 0xff,
1761 destination_mac
.ether_addr_octet
[2] & 0xff,
1762 destination_mac
.ether_addr_octet
[3] & 0xff,
1763 destination_mac
.ether_addr_octet
[4] & 0xff,
1764 destination_mac
.ether_addr_octet
[5] & 0xff);
1766 printf("Kernel map size is %llu\n", (unsigned long long) get_vmmap_size(kernel_map
));
1767 printf("Sending write request for %s\n", corename_str
);
1769 if ((panic_error
= kdp_send_crashdump_pkt(KDP_WRQ
, corename_str
, 0 , NULL
)) < 0) {
1770 printf ("kdp_send_crashdump_pkt failed with error %d\n", panic_error
);
1771 goto panic_dump_exit
;
1774 /* Just the panic log requested */
1775 if ((panicstr
!= (char *) 0) && (kdp_flag
& PANIC_LOG_DUMP
)) {
1776 printf("Transmitting panic log, please wait: ");
1777 kdp_send_crashdump_data(KDP_DATA
, corename_str
,
1778 debug_buf_ptr
- debug_buf
,
1780 kdp_send_crashdump_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1781 printf("Please file a bug report on this panic, if possible.\n");
1782 goto panic_dump_exit
;
1785 /* maybe we wanted the systemlog */
1786 if (kdp_flag
& SYSTEM_LOG_DUMP
) {
1787 long start_off
= msgbufp
->msg_bufx
;
1790 printf("Transmitting system log, please wait: ");
1791 if (start_off
>= msgbufp
->msg_bufr
) {
1792 len
= msgbufp
->msg_size
- start_off
;
1793 kdp_send_crashdump_data(KDP_DATA
, corename_str
, len
,
1794 msgbufp
->msg_bufc
+ start_off
);
1796 /* seek to remove trailing bytes */
1797 if (len
& (SEGSIZE
- 1))
1798 kdp_send_crashdump_seek(corename_str
, len
);
1802 if (start_off
!= msgbufp
->msg_bufr
) {
1803 len
= msgbufp
->msg_bufr
- start_off
;
1804 kdp_send_crashdump_data(KDP_DATA
, corename_str
, len
,
1805 msgbufp
->msg_bufc
+ start_off
);
1808 kdp_send_crashdump_pkt (KDP_EOF
, NULL
, 0, ((void *) 0));
1809 goto panic_dump_exit
;
1812 /* We want a core dump if we're here */
1816 abort_panic_transfer();
1824 abort_panic_transfer(void)
1826 flag_panic_dump_in_progress
= FALSE
;
1827 flag_dont_abort_panic_dump
= FALSE
;
1832 #if CONFIG_SERIAL_KDP
1834 static boolean_t needs_serial_init
= TRUE
;
1837 kdp_serial_send(void *rpkt
, unsigned int rpkt_len
)
1839 if (needs_serial_init
)
1842 needs_serial_init
= FALSE
;
1846 kdp_serialize_packet((unsigned char *)rpkt
, rpkt_len
, serial_putc
);
1850 kdp_serial_receive(void *rpkt
, unsigned int *rpkt_len
, unsigned int timeout
)
1853 uint64_t now
, deadline
;
1855 if (needs_serial_init
)
1858 needs_serial_init
= FALSE
;
1861 clock_interval_to_deadline(timeout
, 1000 * 1000 /* milliseconds */, &deadline
);
1864 for(clock_get_uptime(&now
); now
< deadline
; clock_get_uptime(&now
))
1866 readkar
= serial_getc();
1869 unsigned char *packet
;
1870 // printf("got char %02x\n", readkar);
1871 if((packet
= kdp_unserialize_packet(readkar
,rpkt_len
)))
1873 memcpy(rpkt
, packet
, *rpkt_len
);
1881 static void kdp_serial_callout(__unused
void *arg
, kdp_event_t event
)
1883 /* When we stop KDP, set the bit to re-initialize the console serial port
1884 * the next time we send/receive a KDP packet. We don't do it on
1885 * KDP_EVENT_ENTER directly because it also gets called when we trap to KDP
1886 * for non-external debugging, i.e., stackshot or core dumps.
1888 * Set needs_serial_init on exit (and initialization, see above) and not
1889 * enter because enter is sent multiple times and causes excess reinitialization.
1894 case KDP_EVENT_PANICLOG
:
1895 case KDP_EVENT_ENTER
:
1897 case KDP_EVENT_EXIT
:
1898 needs_serial_init
= TRUE
;
1903 #endif /* CONFIG_SERIAL_KDP */
1908 #if CONFIG_SERIAL_KDP
1910 struct in_addr ipaddr
;
1911 struct ether_addr macaddr
;
1915 //serial will be the debugger, unless match name is explicitly provided, and it's not "serial"
1916 if(PE_parse_boot_argn("kdp_match_name", kdpname
, sizeof(kdpname
)) && strncmp(kdpname
, "serial", sizeof(kdpname
)) != 0)
1919 // serial must be explicitly requested
1920 if(!PE_parse_boot_argn("kdp_match_name", kdpname
, sizeof(kdpname
)) || strncmp(kdpname
, "serial", sizeof(kdpname
)) != 0)
1924 kprintf("Intializing serial KDP\n");
1926 kdp_register_callout(kdp_serial_callout
, NULL
);
1927 kdp_register_send_receive(kdp_serial_send
, kdp_serial_receive
);
1929 /* fake up an ip and mac for early serial debugging */
1930 macaddr
.ether_addr_octet
[0] = 's';
1931 macaddr
.ether_addr_octet
[1] = 'e';
1932 macaddr
.ether_addr_octet
[2] = 'r';
1933 macaddr
.ether_addr_octet
[3] = 'i';
1934 macaddr
.ether_addr_octet
[4] = 'a';
1935 macaddr
.ether_addr_octet
[5] = 'l';
1936 ipaddr
.s_addr
= 0xABADBABE;
1937 kdp_set_ip_and_mac_addresses(&ipaddr
, &macaddr
);
1938 #endif /* CONFIG_SERIAL_KDP */