* Callback from dumpsys() to dump a chunk of memory. * Copies it out to our static buffer then sends it across the network. * Detects the initial KDH and makes sure it is given a special packet type. * * Parameters: * priv Unused. Optional private pointer. * virtual Virtual address (where to read the data from) * physical Unused. Physical memory address. * offset Offset from start of co
| 234 | * errno on error |
| 235 | */ |
| 236 | static int |
| 237 | netdump_dumper(void *priv __unused, void *virtual, |
| 238 | vm_offset_t physical __unused, off_t offset, size_t length) |
| 239 | { |
| 240 | int error; |
| 241 | |
| 242 | NETDDEBUGV("netdump_dumper(NULL, %p, NULL, %ju, %zu)\n", |
| 243 | virtual, (uintmax_t)offset, length); |
| 244 | |
| 245 | if (virtual == NULL) { |
| 246 | error = netdump_flush_buf(); |
| 247 | if (error != 0) |
| 248 | dump_failed = 1; |
| 249 | |
| 250 | if (dump_failed != 0) |
| 251 | printf("failed to dump the kernel core\n"); |
| 252 | else if ( |
| 253 | debugnet_sendempty(nd_conf.nd_pcb, DEBUGNET_FINISHED) != 0) |
| 254 | printf("failed to close the transaction\n"); |
| 255 | else |
| 256 | printf("\nnetdump finished.\n"); |
| 257 | debugnet_free(nd_conf.nd_pcb); |
| 258 | nd_conf.nd_pcb = NULL; |
| 259 | return (0); |
| 260 | } |
| 261 | if (length > sizeof(nd_buf)) |
| 262 | return (ENOSPC); |
| 263 | |
| 264 | if (nd_conf.nd_buf_len + length > sizeof(nd_buf) || |
| 265 | (nd_conf.nd_buf_len != 0 && nd_conf.nd_tx_off + |
| 266 | nd_conf.nd_buf_len != offset)) { |
| 267 | error = netdump_flush_buf(); |
| 268 | if (error != 0) { |
| 269 | dump_failed = 1; |
| 270 | return (error); |
| 271 | } |
| 272 | nd_conf.nd_tx_off = offset; |
| 273 | } |
| 274 | |
| 275 | memmove(nd_buf + nd_conf.nd_buf_len, virtual, length); |
| 276 | nd_conf.nd_buf_len += length; |
| 277 | |
| 278 | return (0); |
| 279 | } |
| 280 | |
| 281 | /* |
| 282 | * Perform any initialization needed prior to transmitting the kernel core. |
nothing calls this directly
no test coverage detected