int get_next_line(int fd, char **line) { static t_buf save[MAX_FILES]; char *buffer; char *tmp2; char *br; ssize_t ret; X; if (!GETBUF(fd)) GETBUF(fd) = ft_memalloc(1); while (!(br = ft_strchr(GETOFFSET(fd), '\n')) && (ret = read(fd, buffer, BUFF_SIZE)) > 0) { GETREAD(fd) += ret; buffer[ret] = '\0'; SWAP(GETBUF(fd), ft_strjoin(GETOFFSET(fd), buffer), tmp2); GETREADED(fd) = 0; } if (ft_strlen(GETOFFSET(fd)) == 0 && ret == 0) OHOHOHAHAHAH; if (GETREAD(fd) == -1 || ret < 0 || (ret = ft_cpybuf(GETOFFSET(fd), line, br, save[fd])) == -1) return (-1); GETREADED(fd) += (GETOFFSET(fd)[ret] != 0) ? ret + 1 : ret; GETREAD(fd) -= (GETOFFSET(fd)[ret] != 0) ? ret + 1 : ret; return (1); }
/* * Quickest way to gdb -- just pass a command string to pass through. */ int gdb_pass_through(char *cmd, FILE *fptr, ulong flags) { struct gnu_request *req; int retval; if (CRASHDEBUG(1)) console("gdb_pass_through: [%s]\n", cmd); req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); req->buf = cmd; if (fptr) req->fp = fptr; req->command = GNU_PASS_THROUGH; req->flags = flags; gdb_interface(req); if ((req->flags & (GNU_RETURN_ON_ERROR|GNU_COMMAND_FAILED)) == (GNU_RETURN_ON_ERROR|GNU_COMMAND_FAILED)) retval = FALSE; else retval = TRUE; FREEBUF(req); return retval; }
size_t dirtio_allocv(struct diodevice *dio, struct iovec *iovec, int num, size_t len) { int i, n, b; struct iovec *iov = iovec; n = 0; for (i = 0; i < DIRTIO_BUFBMAPSZ(dio); i++) { printf("dio->bmap[i] = %llx\n", dio->bmap[i]); while (dio->bmap[i] != (uint64_t)-1) { b = ffs64(~dio->bmap[i]) - 1; assert(b != -1); dio->bmap[i] |= ((uint64_t)1 << b); iov->iov_base = GETBUF(dio, i * 64 + b); iov->iov_len = len < dio->bufsz ? len : dio->bufsz; len -= iov->iov_len; iov++; n++; if (len == 0 || n == num) goto out; } } out: return len; }
static int wpacket_intern_init_len(WPACKET *pkt, size_t lenbytes) { unsigned char *lenchars; pkt->curr = 0; pkt->written = 0; pkt->subs = OPENSSL_zalloc(sizeof(*pkt->subs)); if (pkt->subs == NULL) return 0; if (lenbytes == 0) return 1; pkt->subs->pwritten = lenbytes; pkt->subs->lenbytes = lenbytes; if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) { OPENSSL_free(pkt->subs); pkt->subs = NULL; return 0; } pkt->subs->packet_len = lenchars - GETBUF(pkt); return 1; }
void efe_ring_free(efe_ring_t **rpp) { efe_ring_t *rp = *rpp; ASSERT(rp != NULL); for (int i = 0; i < DESCLEN(rp); ++i) { efe_buf_t *bp = GETBUF(rp, i); if (bp != NULL) { efe_buf_free(&bp); } } kmem_free(rp->r_bufpp, BUFPSZ(DESCLEN(rp))); if (rp->r_descp != NULL) { (void) ddi_dma_unbind_handle(rp->r_dmah); } if (rp->r_acch != NULL) { ddi_dma_mem_free(&rp->r_acch); } if (rp->r_dmah != NULL) { ddi_dma_free_handle(&rp->r_dmah); } kmem_free(rp, sizeof (efe_ring_t)); *rpp = NULL; }
int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes) { WPACKET_SUB *sub; unsigned char *lenchars; /* Internal API, so should not fail */ if (!ossl_assert(pkt->subs != NULL)) return 0; sub = OPENSSL_zalloc(sizeof(*sub)); if (sub == NULL) return 0; sub->parent = pkt->subs; pkt->subs = sub; sub->pwritten = pkt->written + lenbytes; sub->lenbytes = lenbytes; if (lenbytes == 0) { sub->packet_len = 0; return 1; } if (!WPACKET_allocate_bytes(pkt, lenbytes, &lenchars)) return 0; /* Convert to an offset in case the underlying BUF_MEM gets realloc'd */ sub->packet_len = lenchars - GETBUF(pkt); return 1; }
void efe_init_tx_ring(efe_t *efep) { efe_ring_t *rp; ASSERT(mutex_owned(&efep->efe_txlock)); rp = efep->efe_tx_ring; for (int i = 0; i < DESCLEN(rp); ++i) { efe_desc_t *dp = GETDESC(rp, i); efe_buf_t *bp = GETBUF(rp, i); PUTDESC16(rp, &dp->d_status, 0); PUTDESC16(rp, &dp->d_len, 0); PUTDESC32(rp, &dp->d_bufaddr, BUFADDR(bp)); PUTDESC16(rp, &dp->d_buflen, BUFLEN(bp)); PUTDESC16(rp, &dp->d_control, 0); PUTDESC32(rp, &dp->d_next, NEXTDESCADDR(rp, i)); SYNCDESC(rp, i, DDI_DMA_SYNC_FORDEV); } efep->efe_tx_desc = 0; efep->efe_tx_sent = 0; PUTCSR(efep, CSR_PTCDAR, DESCADDR(rp, 0)); }
void map_cpus_to_prstatus_kdump_cmprs(void) { void **nt_ptr; int online, i, j, nrcpus; size_t size; if (!(online = get_cpus_online()) || (online == kt->cpus)) return; if (CRASHDEBUG(1)) error(INFO, "cpus: %d online: %d NT_PRSTATUS notes: %d (remapping)\n", kt->cpus, online, dd->num_prstatus_notes); size = NR_CPUS * sizeof(void *); nt_ptr = (void **)GETBUF(size); BCOPY(dd->nt_prstatus_percpu, nt_ptr, size); BZERO(dd->nt_prstatus_percpu, size); /* * Re-populate the array with the notes mapping to online cpus */ nrcpus = (kt->kernel_NR_CPUS ? kt->kernel_NR_CPUS : NR_CPUS); for (i = 0, j = 0; i < nrcpus; i++) { if (in_cpu_map(ONLINE, i)) dd->nt_prstatus_percpu[i] = nt_ptr[j++]; } FREEBUF(nt_ptr); }
/* * Check whether string in args[0] is a valid gdb command. */ int is_gdb_command(int merge_orig_args, ulong flags) { int retval; struct gnu_request *req; if (!args[0]) return FALSE; if (STREQ(args[0], "Q")) { args[0] = "q"; return TRUE; } if (is_restricted_command(args[0], flags)) return FALSE; req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); req->buf = GETBUF(strlen(args[0])+1); req->command = GNU_COMMAND_EXISTS; req->name = args[0]; req->flags = GNU_RETURN_ON_ERROR; req->fp = pc->nullfp; gdb_interface(req); if (req->flags & GNU_COMMAND_FAILED) retval = FALSE; else retval = req->value; FREEBUF(req->buf); FREEBUF(req); if (retval && merge_orig_args) { int i; for (i = argcnt; i; i--) args[i] = args[i-1]; args[0] = "gdb"; argcnt++; } return retval; }
mblk_t * efe_recv_pkt(efe_t *efep, efe_desc_t *dp) { efe_ring_t *rp; efe_buf_t *bp; uint16_t len; mblk_t *mp; uint16_t status; ASSERT(mutex_owned(&efep->efe_intrlock)); rp = efep->efe_rx_ring; len = GETDESC16(rp, &dp->d_len) - ETHERFCSL; if (len < ETHERMIN) { efep->efe_ierrors++; efep->efe_runt_errors++; return (NULL); } if (len > ETHERMAX + VLAN_TAGSZ) { efep->efe_ierrors++; efep->efe_toolong_errors++; return (NULL); } mp = allocb(len, 0); if (mp == NULL) { efep->efe_ierrors++; efep->efe_norcvbuf++; return (NULL); } mp->b_wptr = mp->b_rptr + len; bp = GETBUF(rp, efep->efe_rx_desc); SYNCBUF(bp, DDI_DMA_SYNC_FORKERNEL); bcopy(bp->b_kaddr, mp->b_rptr, len); efep->efe_ipackets++; efep->efe_rbytes += len; status = GETDESC16(rp, &dp->d_status); if (status & RXSTAT_BAR) { efep->efe_brdcstrcv++; } else if (status & RXSTAT_MAR) { efep->efe_multircv++; } return (mp); }
struct netent * getnetent(void) { nss_XbyY_buf_t *b; struct netent *res = 0; if ((b = GETBUF()) != 0) { res = getnetent_r(b->result, b->buffer, b->buflen); } return (res); }
struct netent * getnetbyname(const char *nam) { nss_XbyY_buf_t *b; struct netent *res = 0; if ((b = GETBUF()) != 0) { res = getnetbyname_r(nam, b->result, b->buffer, b->buflen); } return (res); }
struct netent * getnetbyaddr(in_addr_t net, int type) { nss_XbyY_buf_t *b; struct netent *res = 0; if ((b = GETBUF()) != 0) { res = getnetbyaddr_r(net, type, b->result, b->buffer, b->buflen); } return (res); }
int dwarf_print_stack_entry(struct bt_info *bt, int level) { unsigned long offset; struct syment *sp; char *name; struct unwind_frame_info *frame; frame = (struct unwind_frame_info *)GETBUF(sizeof(struct unwind_frame_info)); UNW_SP(frame) = bt->stkptr; UNW_PC(frame) = bt->instptr; sp = value_search(UNW_PC(frame), &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)); goto bailout; } /* * If offset is zero, it means we have crossed over to the next * function. Recalculate by adjusting the text address */ if (!offset) { sp = value_search(UNW_PC(frame) - 1, &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)-1); goto bailout; } } name = sp->name; fprintf(fp, " #%d [%016lx] %s at %016lx \n", level, UNW_SP(frame), name, UNW_PC(frame)); bailout: FREEBUF(frame); return level; }
void dwarf_debug(struct bt_info *bt) { struct unwind_frame_info *frame; ulong bp; int is_ehframe = (!st->dwarf_debug_frame_size && st->dwarf_eh_frame_size); if (!bt->hp->eip) { dump_local_unwind_tables(); return; } if (!(kt->flags & DWARF_UNWIND_CAPABLE)) { error(INFO, "not DWARF capable\n"); return; } frame = (struct unwind_frame_info *)GETBUF(sizeof(struct unwind_frame_info)); /* * XXX: This only works for the first PC/SP pair seen in a normal * backtrace, so it's not particularly helpful. Ideally it should * be capable to take any PC/SP pair in a stack, but it appears to * related to the rbp value. */ UNW_PC(frame) = bt->hp->eip; UNW_SP(frame) = bt->hp->esp; readmem(UNW_SP(frame), KVADDR, &bp, sizeof(unsigned long), "reading bp", FAULT_ON_ERROR); frame->regs.rbp = bp; /* fixme for x86 */ unwind(frame, is_ehframe); fprintf(fp, "frame size: %lx (%lx)\n", (ulong)UNW_SP(frame), (ulong)UNW_SP(frame) - bt->hp->esp); FREEBUF(frame); }
/* * Internal helper function used by WPACKET_close(), WPACKET_finish() and * WPACKET_fill_lengths() to close a sub-packet and write out its length if * necessary. If |doclose| is 0 then it goes through the motions of closing * (i.e. it fills in all the lengths), but doesn't actually close anything. */ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose) { size_t packlen = pkt->written - sub->pwritten; if (packlen == 0 && (sub->flags & WPACKET_FLAGS_NON_ZERO_LENGTH) != 0) return 0; if (packlen == 0 && sub->flags & WPACKET_FLAGS_ABANDON_ON_ZERO_LENGTH) { /* We can't handle this case. Return an error */ if (!doclose) return 0; /* Deallocate any bytes allocated for the length of the WPACKET */ if ((pkt->curr - sub->lenbytes) == sub->packet_len) { pkt->written -= sub->lenbytes; pkt->curr -= sub->lenbytes; } /* Don't write out the packet length */ sub->packet_len = 0; sub->lenbytes = 0; } /* Write out the WPACKET length if needed */ if (sub->lenbytes > 0 && !put_value(&GETBUF(pkt)[sub->packet_len], packlen, sub->lenbytes)) return 0; if (doclose) { pkt->subs = sub->parent; OPENSSL_free(sub); } return 1; }
static FILE *open_output_file(const char *dname, const char *fname) { FILE *filp = NULL; char *output_file; output_file = GETBUF(sizeof(char) * (strlen(dname) + strlen(fname) + 2)); if (output_file == NULL) { error(FATAL, "cannot allocate memory for logfile name '%s%s'\n", dname, fname); } create_output_dir(dname); sprintf(output_file,"%s/%s", dname, fname); filp = fopen(output_file, "w"); if (!filp) { error(FATAL, "cannot create log file '%s'\n", output_file); } FREEBUF(output_file); return filp; }
char * generate_elf_header(int type, int fd, char *filename) { int i, n; char *buffer, *ptr; Elf64_Ehdr *elf; Elf64_Phdr *notes; Elf64_Phdr *load; size_t offset, len, l_offset; size_t data_offset; struct elf_prpsinfo_64 prpsinfo; union prstatus prstatus; int prstatus_len; ushort e_machine; int num_segments; struct node_table *nt; struct SNAP_info { ulonglong task_struct; ulonglong arch_data1; ulonglong arch_data2; } SNAP_info; num_segments = vt->numnodes; if (machine_type("X86_64")) { e_machine = EM_X86_64; prstatus_len = sizeof(prstatus.x86_64); num_segments += 1; /* mapped kernel section for phys_base */ } else if (machine_type("X86")) { e_machine = EM_386; prstatus_len = sizeof(prstatus.x86); } else if (machine_type("IA64")) { e_machine = EM_IA_64; prstatus_len = sizeof(prstatus.ia64); num_segments += 1; /* mapped kernel section for phys_start */ } else if (machine_type("PPC64")) { e_machine = EM_PPC64; prstatus_len = sizeof(prstatus.ppc64); } else if (machine_type("ARM64")) { e_machine = EM_AARCH64; prstatus_len = sizeof(prstatus.arm64); } else return NULL; /* should be enought for the notes + roundup + two blocks */ buffer = (char *)GETBUF(sizeof(Elf64_Ehdr) + num_segments * sizeof(Elf64_Phdr) + PAGESIZE() * 2); offset = 0; ptr = buffer; /* Elf header */ elf = (Elf64_Ehdr *)ptr; memcpy(elf->e_ident, ELFMAG, SELFMAG); elf->e_ident[EI_CLASS] = ELFCLASS64; #if __BYTE_ORDER == __BIG_ENDIAN elf->e_ident[EI_DATA] = ELFDATA2MSB; #else elf->e_ident[EI_DATA] = ELFDATA2LSB; #endif elf->e_ident[EI_VERSION] = EV_CURRENT; elf->e_ident[EI_OSABI] = ELFOSABI_SYSV; elf->e_ident[EI_ABIVERSION] = 0; memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD); elf->e_type = ET_CORE; elf->e_machine = e_machine; elf->e_version = EV_CURRENT; elf->e_entry = 0; elf->e_phoff = sizeof(Elf64_Ehdr); elf->e_shoff = 0; elf->e_flags = 0; elf->e_ehsize = sizeof(Elf64_Ehdr); elf->e_phentsize = sizeof(Elf64_Phdr); elf->e_phnum = 1 + num_segments; elf->e_shentsize = 0; elf->e_shnum = 0; elf->e_shstrndx = 0; offset += sizeof(Elf64_Ehdr); ptr += sizeof(Elf64_Ehdr); /* PT_NOTE */ notes = (Elf64_Phdr *)ptr; notes->p_type = PT_NOTE; notes->p_offset = 0; /* TO BE FILLED IN */ notes->p_vaddr = 0; notes->p_paddr = 0; notes->p_filesz = 0; /* TO BE FILLED IN */ notes->p_memsz = 0; notes->p_flags = 0; notes->p_align = 0; offset += sizeof(Elf64_Phdr); ptr += sizeof(Elf64_Phdr); /* PT_LOAD */ load = (Elf64_Phdr *)ptr; for (i = n = 0; i < num_segments; i++) { load[i].p_type = PT_LOAD; load[i].p_offset = 0; /* TO BE FILLED IN */ switch (e_machine) { case EM_X86_64: nt = &vt->node_table[n]; if (i == 0) { #ifdef X86_64 load[i].p_vaddr = __START_KERNEL_map; load[i].p_paddr = machdep->machspec->phys_base; #endif load[i].p_filesz = 0; load[i].p_memsz = load[i].p_filesz; } else { load[i].p_vaddr = PTOV(nt->start_paddr); load[i].p_paddr = nt->start_paddr; load[i].p_filesz = nt->size * PAGESIZE(); load[i].p_memsz = load[i].p_filesz; n++; } load[i].p_flags = PF_R | PF_W | PF_X; load[i].p_align = 0; break; case EM_386: nt = &vt->node_table[n++]; load[i].p_vaddr = 0; load[i].p_paddr = nt->start_paddr; load[i].p_filesz = nt->size * PAGESIZE(); load[i].p_memsz = load[i].p_filesz; load[i].p_flags = PF_R | PF_W | PF_X; load[i].p_align = (type == NETDUMP_ELF64) ? PAGESIZE() : 0; break; case EM_IA_64: nt = &vt->node_table[n]; if (i == 0) { #ifdef IA64 load[i].p_vaddr = machdep->machspec->kernel_start; load[i].p_paddr = machdep->machspec->phys_start; #endif load[i].p_filesz = 0; load[i].p_memsz = load[i].p_filesz; } else { load[i].p_vaddr = PTOV(nt->start_paddr); load[i].p_paddr = nt->start_paddr; load[i].p_filesz = nt->size * PAGESIZE(); load[i].p_memsz = load[i].p_filesz; n++; } load[i].p_flags = PF_R | PF_W | PF_X; load[i].p_align = (type == NETDUMP_ELF64) ? PAGESIZE() : 0; break; case EM_PPC64: nt = &vt->node_table[n++]; load[i].p_vaddr = PTOV(nt->start_paddr); load[i].p_paddr = nt->start_paddr; load[i].p_filesz = nt->size * PAGESIZE(); load[i].p_memsz = load[i].p_filesz; load[i].p_flags = PF_R | PF_W | PF_X; load[i].p_align = (type == NETDUMP_ELF64) ? PAGESIZE() : 0; break; case EM_AARCH64: nt = &vt->node_table[n++]; load[i].p_vaddr = PTOV(nt->start_paddr); load[i].p_paddr = nt->start_paddr; load[i].p_filesz = nt->size * PAGESIZE(); load[i].p_memsz = load[i].p_filesz; load[i].p_flags = PF_R | PF_W | PF_X; load[i].p_align = (type == NETDUMP_ELF64) ? PAGESIZE() : 0; break; } // l_offset += load[i].p_filesz; offset += sizeof(Elf64_Phdr); ptr += sizeof(Elf64_Phdr); } notes->p_offset = offset; /* NT_PRSTATUS note */ memset(&prstatus, 0, sizeof(prstatus)); len = dump_elf_note(ptr, NT_PRSTATUS, "CORE", (char *)&prstatus, prstatus_len); offset += len; ptr += len; notes->p_filesz += len; /* NT_PRPSINFO note */ memset(&prpsinfo, 0, sizeof(struct elf_prpsinfo_64)); prpsinfo.pr_state = 0; prpsinfo.pr_sname = 'R'; prpsinfo.pr_zomb = 0; strcpy(prpsinfo.pr_fname, "vmlinux"); len = dump_elf_note(ptr, NT_PRPSINFO, "CORE", (char *)&prpsinfo, sizeof(prpsinfo)); offset += len; ptr += len; notes->p_filesz += len; /* NT_TASKSTRUCT note */ SNAP_info.task_struct = CURRENT_TASK(); #ifdef X86_64 SNAP_info.arch_data1 = kt->relocate; SNAP_info.arch_data2 = 0; #elif ARM64 SNAP_info.arch_data1 = machdep->machspec->kimage_voffset; SNAP_info.arch_data2 = (machdep->machspec->VA_BITS_ACTUAL << 32) | machdep->machspec->CONFIG_ARM64_VA_BITS; #else SNAP_info.arch_data1 = 0; SNAP_info.arch_data2 = 0; #endif len = dump_elf_note (ptr, NT_TASKSTRUCT, "SNAP", (char *)&SNAP_info, sizeof(struct SNAP_info)); offset += len; ptr += len; notes->p_filesz += len; if (type == NETDUMP_ELF64) offset = roundup (offset, PAGESIZE()); l_offset = offset; for (i = 0; i < num_segments; i++) { load[i].p_offset = l_offset; l_offset += load[i].p_filesz; } data_offset = offset; while (offset > 0) { len = write(fd, buffer + (data_offset - offset), offset); if (len < 0) { perror(filename); FREEBUF(buffer); return NULL; } offset -= len; } return buffer; }
static void init_ram_segments(void) { int i, errflag; FILE *iomem; char buf[BUFSIZE], *p1, *p2; physaddr_t start, end; if ((iomem = fopen("/proc/iomem", "r")) == NULL) goto fail_iomem; while (fgets(buf, BUFSIZE, iomem)) { if (strstr(buf, "System RAM")) { console(buf); nr_segments++; } } if (!nr_segments) goto fail_iomem; ram_segments = (struct ram_segments *) GETBUF(sizeof(struct ram_segments) * nr_segments); rewind(iomem); i = 0; while (fgets(buf, BUFSIZE, iomem)) { if (strstr(buf, "System RAM")) { if (!(p1 = strstr(buf, ":"))) goto fail_iomem; *p1 = NULLCHAR; clean_line(buf); if (strstr(buf, " ")) goto fail_iomem; p1 = buf; if (!(p2 = strstr(buf, "-"))) goto fail_iomem; *p2 = NULLCHAR; p2++; errflag = 0; start = htoll(p1, RETURN_ON_ERROR|QUIET, &errflag); end = htoll(p2, RETURN_ON_ERROR|QUIET, &errflag); if (errflag) goto fail_iomem; ram_segments[i].start = PHYSPAGEBASE(start); if (PAGEOFFSET(start)) ram_segments[i].start += PAGESIZE(); ram_segments[i].end = PHYSPAGEBASE(end); if (PAGEOFFSET(end) == (PAGESIZE()-1)) ram_segments[i].end += PAGESIZE(); console("ram_segments[%d]: %016llx %016llx [%s-%s]\n", i, (ulonglong)ram_segments[i].start, (ulonglong)ram_segments[i].end, p1, p2); i++; } } fclose(iomem); return; fail_iomem: fclose(iomem); nr_segments = 0; if (ram_segments) FREEBUF(ram_segments); return; }
int efe_send(efe_t *efep, mblk_t *mp) { efe_ring_t *rp; uint16_t len; efe_desc_t *dp; uint16_t status; efe_buf_t *bp; ASSERT(mutex_owned(&efep->efe_txlock)); rp = efep->efe_tx_ring; len = msgsize(mp); if (len > ETHERMAX + VLAN_TAGSZ) { efep->efe_oerrors++; efep->efe_macxmt_errors++; freemsg(mp); return (DDI_SUCCESS); } dp = GETDESC(rp, efep->efe_tx_desc); SYNCDESC(rp, efep->efe_tx_desc, DDI_DMA_SYNC_FORKERNEL); status = GETDESC16(efep->efe_tx_ring, &dp->d_status); /* Stop if device owns descriptor */ if (status & TXSTAT_OWNER) { return (DDI_FAILURE); } bp = GETBUF(rp, efep->efe_tx_desc); mcopymsg(mp, bp->b_kaddr); /* * Packets must contain at least ETHERMIN octets. * Padded octets are zeroed out prior to sending. */ if (len < ETHERMIN) { bzero(bp->b_kaddr + len, ETHERMIN - len); len = ETHERMIN; } SYNCBUF(bp, DDI_DMA_SYNC_FORDEV); PUTDESC16(rp, &dp->d_status, TXSTAT_OWNER); PUTDESC16(rp, &dp->d_len, len); PUTDESC16(rp, &dp->d_control, TXCTL_LASTDESCR); SYNCDESC(rp, efep->efe_tx_desc, DDI_DMA_SYNC_FORDEV); efep->efe_opackets++; efep->efe_obytes += len; if (*bp->b_kaddr & 0x01) { if (bcmp(bp->b_kaddr, efe_broadcast, ETHERADDRL) == 0) { efep->efe_brdcstxmt++; } else { efep->efe_multixmt++; } } efep->efe_tx_desc = NEXTDESC(rp, efep->efe_tx_desc); return (DDI_SUCCESS); }
unsigned char *WPACKET_get_curr(WPACKET *pkt) { return GETBUF(pkt) + pkt->curr; }
static void output_cpu_logs(char *dirname) { int i; struct per_cpu_data *pcd; size_t n, idx, start, end, len; size_t padding; char *source, fname[MAX_FNAME + 1]; /* allocate subbuf memory */ subbuf = GETBUF(chan.subbuf_size); if (!subbuf) { error(FATAL, "cannot allocate memory\n"); } for (i = 0; i < kt->cpus; i++) { pcd = &per_cpu[i]; if (pcd->buf.subbufs_produced == 0 && pcd->buf.offset == 0) { if (is_global == 1) { error(WARNING, "There is no data in the relay buffer.\n"); break; } else { error(WARNING, "[cpu:%d]There is no data in the relay buffer.\n", i); continue; } } end = pcd->buf.subbufs_produced + 1; if (pcd->buf.subbufs_produced >= chan.n_subbufs) { start = end - chan.n_subbufs; } else { start = 0; } create_output_filename(fname, MAX_FNAME, i); fprintf(fp, "--- generating '%s/%s' ---\n", dirname, fname); fprintf(fp, " subbufs ready on relayfs:%ld\n", (long)end); fprintf(fp, " n_subbufs:%ld, read subbuf from:%ld(%ld) " "to:%ld(%ld) (offset:0-%ld)\n\n", (long)chan.n_subbufs, (long)start, (long)(start % chan.n_subbufs), (long)end-1, (long)((end-1) % chan.n_subbufs), (long) pcd->buf.offset); outfp = open_output_file(dirname, fname); for (n = start; n < end; n++) { /* read relayfs subbufs and write to log file */ idx = n % chan.n_subbufs; source = pcd->buf.start + idx * chan.subbuf_size; if (old_format == 1) { readmem((ulong)pcd->buf.padding + sizeof(unsigned) * idx, KVADDR, &padding, sizeof(unsigned), "padding", FAULT_ON_ERROR); } else { readmem((ulong)pcd->buf.padding + sizeof(padding) * idx, KVADDR, &padding, sizeof(padding), "padding", FAULT_ON_ERROR); } if (n == end - 1) { len = pcd->buf.offset; } else { len = chan.subbuf_size; } if (old_format == 1) { source += sizeof(unsigned int); len -= sizeof(unsigned int) + padding; } else { len -= padding; } if (len > 0) { readmem((ulong)source, KVADDR, subbuf, len, "subbuf", FAULT_ON_ERROR); if (fwrite(subbuf, len, 1, outfp) != 1) { error(FATAL, "cannot write log data\n"); } } } fclose(outfp); outfp = NULL; /* * -a option retrieve the old data of subbuffer where the * probe record is written at that time. */ if (retrieve_all == 1 && start != 0) { strncat(fname, ".may_broken", MAX_FNAME); fprintf(fp, "--- generating '%s/%s' ---\n", dirname, fname); fprintf(fp, " read subbuf %ld(%ld) (offset:%ld-%ld)\n", (long)start-1, (long)((start-1) % chan.n_subbufs), (long)pcd->buf.offset, (long)chan.subbuf_size); outfp = open_output_file(dirname, fname); idx = (start - 1) % chan.n_subbufs; source = pcd->buf.start + idx * chan.subbuf_size + pcd->buf.offset; len = chan.subbuf_size - pcd->buf.offset; if (len) { readmem((ulong)source, KVADDR, subbuf, len, "may_broken_subbuf", FAULT_ON_ERROR); if (fwrite(subbuf, len, 1, outfp) != 1) { error(FATAL, "cannot write log data(may_broken)\n"); } } fclose(outfp); outfp = NULL; } if (is_global == 1) break; } if (subbuf) { FREEBUF(subbuf); subbuf = NULL; } return; }
int mon_3c905_ethintr() { STATWORD ps; struct dev_3c905* dev; struct eth_pd* epd; unsigned long intst, txst; disable(ps); dev = &mon_dev_eth; _3CCMD(dev, _3C905_CMD_SETINTERRUPT, 0); /* get status */ intst = inw(dev->iobase + _3C905_OFF_INTSTATUS); /* not our interrupt */ if (! (intst & _3C905_FLG_INTERRUPT)) { _3CCMD(dev, _3C905_CMD_SETINTERRUPT, _3C905_MSK_INTERRUPTS); restore(ps); return(OK); } /* acknowledge interrupt */ _3CCMD(dev, _3C905_CMD_ACKINTERRUPT, _3C905_FLG_INTERRUPT); while(1) { /* get status */ intst = inw(dev->iobase + _3C905_OFF_INTSTATUS) & _3C905_MSK_INTERRUPTS; #ifdef DEBUG kprintf("is=0x%x upp=0x%x dnp=0x%x\n", intst, inl(dev->iobase + _3C905_OFF_UPLISTPTR), inl(dev->iobase + _3C905_OFF_DNLISTPTR)); #endif if (intst == 0) break; if (intst & _3C905_FLG_UPCOMPLINT) { _3CCMD(dev, _3C905_CMD_ACKINTERRUPT, _3C905_FLG_UPCOMPLINT); mon_3c905_ethdemux(dev); } if (intst & _3C905_FLG_TXCOMPLINT) { mon_3c905_ethxintr(dev); txst = inb(dev->iobase + _3C905_OFF_TXSTATUS); outb(dev->iobase + _3C905_OFF_TXSTATUS, 1); } if (dev->state & _3C905_STT_RECLAIM) { while (1) { epd = &mon_eth_rxring[dev->rx_begin]; if (epd->status == 0 || epd->buffer != 0) { dev->state &= ~_3C905_STT_RECLAIM; break; } epd->buffer = (void*) GETBUF(mon_Net.netpool); if (epd->buffer == (void *)0 || epd->buffer == (void *)SYSERR) { epd->buffer = 0; break; } epd->status = 0; epd->buffer = (void*) epd->buffer + sizeof(struct ehx); epd->length = _3C905_FLG_LASTFRAG | EP_MAXLEN; dev->rx_begin = (dev->rx_begin + 1) % _3C905_RXRING; } } } #ifdef DEBUG kprintf("ethintr: leave\n"); #endif _3CCMD(dev, _3C905_CMD_SETINTERRUPT, _3C905_MSK_INTERRUPTS); restore(ps); return(OK); }
int mon_3c905_ethinit () { struct dev_3c905* dev; struct netif* pni; struct ethdev* ped; unsigned short status; unsigned char* buf; int i; dev = &mon_dev_eth; dev->state = 0; /* read config information */ mon_pci_bios_read_config_dword(dev->pcidev, _3C905_PCI_IOBASE, &dev->iobase); mon_pci_bios_read_config_dword(dev->pcidev, _3C905_PCI_MEMBASE, &dev->membase); mon_pci_bios_read_config_byte (dev->pcidev, _3C905_PCI_IRQ, &dev->irq); /* the low bit is set to indicate I/O */ dev->iobase &= ~1; /* if mem address is below 1 MB */ dev->membase &= ~2; /* enable PCI bus master */ mon_pci_bios_read_config_word(dev->pcidev, PCI_COMMAND, &status); status |= PCI_BUSMASTER; mon_pci_bios_write_config_word(dev->pcidev, PCI_COMMAND, status); /* read the MAC address */ _3CSEL(dev, 2); *((unsigned short*) &dev->hwa[0]) = inw(dev->iobase + 0x00); *((unsigned short*) &dev->hwa[2]) = inw(dev->iobase + 0x02); *((unsigned short*) &dev->hwa[4]) = inw(dev->iobase + 0x04); /* enable this to "emulate" xinu109 *((unsigned short*) &dev->hwa[0]) = 0xAA00; *((unsigned short*) &dev->hwa[2]) = 0xA300; *((unsigned short*) &dev->hwa[4]) = 0x8A75; outw(dev->iobase + 0x00, *((unsigned short*) &dev->hwa[0])); outw(dev->iobase + 0x02, *((unsigned short*) &dev->hwa[2])); outw(dev->iobase + 0x04, *((unsigned short*) &dev->hwa[4])); */ #ifdef BOOT_MONITOR *((unsigned short*) &dev->hwa[0]) |= 0xFF01; #endif /* initialize TX/RX rings */ mon_eth_txring = (struct eth_pd*) (((unsigned long) txring + 0xF) & ~0xF); mon_eth_rxring = (struct eth_pd*) (((unsigned long) rxring + 0xF) & ~0xF); for (i = 0; i < _3C905_RXRING; i++) { mon_eth_rxring[i].next = &mon_eth_rxring[(i + 1) % _3C905_RXRING]; mon_eth_rxring[i].status = 0; buf = (unsigned char*) GETBUF(mon_Net.netpool); if (buf == (unsigned char *)SYSERR || buf == (unsigned char *)0) { kprintf("No buffer in ethinit()"); panic("could not allocate buffer for monitor"); } mon_eth_rxring[i].buffer = (void*) buf + sizeof(struct ehx); mon_eth_rxring[i].length = _3C905_FLG_LASTFRAG | EP_MAXLEN; } dev->rx_begin = 0; bzero(mon_eth_txring, sizeof(struct eth_pd) * _3C905_TXRING); dev->tx_begin = 0; dev->tx_end = _3C905_TXRING - 1; /* reset nic */ ethcmdwait(dev, _3C905_CMD_RXRESET, 0x7); ethcmdwait(dev, _3C905_CMD_TXRESET, 0x3); /* enable interrupts */ set_evec(dev->irq + IRQBASE, (unsigned) mon_ethint_hi); _3CCMD(dev, _3C905_CMD_SETINDICATION, _3C905_MSK_INTERRUPTS); _3CCMD(dev, _3C905_CMD_SETINTERRUPT, _3C905_MSK_INTERRUPTS); /* enable receiving and transmission */ _3CCMD(dev, _3C905_CMD_SETRXFILTER, _3C905_MSK_RXFILTER); ethcmdwait(dev, _3C905_CMD_UPSTALL, 0); outl(dev->iobase + _3C905_OFF_UPLISTPTR, (int) mon_eth_rxring); _3CCMD(dev, _3C905_CMD_UPUNSTALL, 0); _3CCMD(dev, _3C905_CMD_RXENABLE, 0); _3CCMD(dev, _3C905_CMD_TXENABLE, 0); /* set the OS structures */ dev->ifn = 0; pni = &mon_nif[0]; pni->ni_write = mon_3c905_ethwrite; ped = &mon_eth[0]; for (i = 0; i < EP_ALEN; i++) { ped->ed_paddr[i] = dev->hwa[i]; ped->ed_bcast[i] = ~0; } ped->ed_irq = dev->irq; return(OK); }
void gdb_session_init(void) { struct gnu_request *req; int debug_data_pulled_in; if (!have_partial_symbols() && !have_full_symbols()) no_debugging_data(FATAL); /* * Restore the SIGINT and SIGPIPE handlers, which got temporarily * re-assigned by gdb. The SIGINT call also initializes GDB's * SIGINT sigaction. */ SIGACTION(SIGINT, restart, &pc->sigaction, &pc->gdb_sigaction); SIGACTION(SIGPIPE, SIG_IGN, &pc->sigaction, NULL); if (!(pc->flags & DROP_CORE)) SIGACTION(SIGSEGV, restart, &pc->sigaction, NULL); /* * Set up pointers to gdb variables. */ #if defined(GDB_5_3) || defined(GDB_6_0) || defined(GDB_6_1) gdb_output_format = &output_format; gdb_print_max = &print_max; gdb_prettyprint_structs = &prettyprint_structs; gdb_prettyprint_arrays = &prettyprint_arrays; gdb_repeat_count_threshold = &repeat_count_threshold; gdb_stop_print_at_null = &stop_print_at_null; gdb_output_radix = &output_radix; #else gdb_output_format = (int *) gdb_user_print_option_address("output_format"); gdb_print_max = (unsigned int *) gdb_user_print_option_address("print_max"); gdb_prettyprint_structs = (int *) gdb_user_print_option_address("prettyprint_structs"); gdb_prettyprint_arrays = (int *) gdb_user_print_option_address("prettyprint_arrays"); gdb_repeat_count_threshold = (int *) gdb_user_print_option_address("repeat_count_threshold"); gdb_stop_print_at_null = (int *) gdb_user_print_option_address("stop_print_at_null"); gdb_output_radix = (unsigned int *) gdb_user_print_option_address("output_radix"); #endif /* * If the output radix is set via the --hex or --dec command line * option, then pc->output_radix will be non-zero; otherwise use * the gdb default. */ if (pc->output_radix) { *gdb_output_radix = pc->output_radix; *gdb_output_format = (*gdb_output_radix == 10) ? 0 : 'x'; } switch (*gdb_output_radix) { case 10: case 16: pc->output_radix = *gdb_output_radix; break; default: pc->output_radix = *gdb_output_radix = 10; *gdb_output_format = 0; } *gdb_prettyprint_structs = 1; *gdb_repeat_count_threshold = 0x7fffffff; *gdb_print_max = 256; #ifdef GDB_5_3 gdb_disassemble_from_exec = 0; #endif pc->flags |= GDB_INIT; /* set here so gdb_interface will work */ req = (struct gnu_request *)GETBUF(sizeof(struct gnu_request)); req->buf = GETBUF(BUFSIZE); /* * Make sure the namelist has symbolic data. Later versions of * gcc may require that debug data be pulled in by printing a * static kernel data structure. */ debug_data_pulled_in = FALSE; retry: BZERO(req->buf, BUFSIZE); req->command = GNU_GET_DATATYPE; req->name = XEN_HYPER_MODE() ? "page_info" : "task_struct"; req->flags = GNU_RETURN_ON_ERROR; gdb_interface(req); if (req->flags & GNU_COMMAND_FAILED) { if (XEN_HYPER_MODE()) no_debugging_data(WARNING); /* just bail out */ if (!debug_data_pulled_in) { if (CRASHDEBUG(1)) error(INFO, "gdb_session_init: pulling in debug data by accessing init_mm.mmap %s\n", symbol_exists("sysfs_mount") ? "and syfs_mount" : ""); debug_data_pulled_in = TRUE; req->command = GNU_PASS_THROUGH; req->flags = GNU_RETURN_ON_ERROR|GNU_NO_READMEM; req->name = NULL; if (symbol_exists("sysfs_mount")) sprintf(req->buf, "print sysfs_mount, init_mm.mmap"); else sprintf(req->buf, "print init_mm.mmap"); gdb_interface(req); if (!(req->flags & GNU_COMMAND_FAILED)) goto retry; } no_debugging_data(WARNING); } if (pc->flags & KERNEL_DEBUG_QUERY) { fprintf(fp, "\n%s: %s: contains debugging data\n\n", pc->program_name, pc->namelist); if (REMOTE()) remote_exit(); clean_exit(0); } /* * Set up any pre-ordained gdb settings here that can't be * accessed directly. */ req->command = GNU_PASS_THROUGH; req->name = NULL, req->flags = 0; sprintf(req->buf, "set height 0"); gdb_interface(req); req->command = GNU_PASS_THROUGH; req->name = NULL, req->flags = 0; sprintf(req->buf, "set width 0"); gdb_interface(req); /* * Patch gdb's symbol values with the correct values from either * the System.map or non-debug vmlinux, whichever is in effect. */ if ((pc->flags & SYSMAP) || (kt->flags & (RELOC_SET|RELOC_FORCE)) || (pc->namelist_debug && !pc->debuginfo_file)) { req->command = GNU_PATCH_SYMBOL_VALUES; req->flags = GNU_RETURN_ON_ERROR; gdb_interface(req); if (req->flags & GNU_COMMAND_FAILED) error(FATAL, "patching of gdb symbol values failed\n"); } else if (!(pc->flags & SILENT)) fprintf(fp, "\n"); FREEBUF(req->buf); FREEBUF(req); }
int dwarf_backtrace(struct bt_info *bt, int level, ulong stacktop) { unsigned long bp, offset; struct syment *sp; char *name; struct unwind_frame_info *frame; int is_ehframe = (!st->dwarf_debug_frame_size && st->dwarf_eh_frame_size); frame = (struct unwind_frame_info *)GETBUF(sizeof(struct unwind_frame_info)); // frame->regs.rsp = bt->stkptr; // frame->regs.rip = bt->instptr; UNW_SP(frame) = bt->stkptr; UNW_PC(frame) = bt->instptr; /* read rbp from stack for non active tasks */ if (!(bt->flags & BT_DUMPFILE_SEARCH) && !bt->bptr) { // readmem(frame->regs.rsp, KVADDR, &bp, readmem(UNW_SP(frame), KVADDR, &bp, sizeof(unsigned long), "reading bp", FAULT_ON_ERROR); frame->regs.rbp = bp; /* fixme for x86 */ } sp = value_search(UNW_PC(frame), &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)); goto bailout; } /* * If offset is zero, it means we have crossed over to the next * function. Recalculate by adjusting the text address */ if (!offset) { sp = value_search(UNW_PC(frame) - 1, &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)-1); goto bailout; } } name = sp->name; fprintf(fp, " #%d [%016lx] %s at %016lx \n", level, UNW_SP(frame), name, UNW_PC(frame)); if (CRASHDEBUG(2)) fprintf(fp, " < SP: %lx PC: %lx FP: %lx >\n", UNW_SP(frame), UNW_PC(frame), frame->regs.rbp); while ((UNW_SP(frame) < stacktop) && !unwind(frame, is_ehframe) && UNW_PC(frame)) { /* To prevent rip pushed on IRQ stack being reported both * both on the IRQ and process stacks */ if ((bt->flags & BT_IRQSTACK) && (UNW_SP(frame) >= stacktop - 16)) break; level++; sp = value_search(UNW_PC(frame), &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)); break; } /* * If offset is zero, it means we have crossed over to the next * function. Recalculate by adjusting the text address */ if (!offset) { sp = value_search(UNW_PC(frame) - 1, &offset); if (!sp) { if (CRASHDEBUG(1)) fprintf(fp, "unwind: cannot find symbol for PC: %lx\n", UNW_PC(frame)-1); goto bailout; } } name = sp->name; fprintf(fp, "%s#%d [%016lx] %s at %016lx \n", level < 10 ? " " : "", level, UNW_SP(frame), name, UNW_PC(frame)); if (CRASHDEBUG(2)) fprintf(fp, " < SP: %lx PC: %lx FP: %lx >\n", UNW_SP(frame), UNW_PC(frame), frame->regs.rbp); } bailout: FREEBUF(frame); return ++level; }
/* * Transfer the relevant data from the kernel and module unwind_table * structures to the local_unwind_table structures. */ static int populate_local_tables(ulong root, char *buf) { struct list_data list_data, *ld; int i, cnt; ulong *table_list; ulong vaddr; struct local_unwind_table *tp; ld = &list_data; BZERO(ld, sizeof(struct list_data)); ld->start = root; ld->member_offset = OFFSET(unwind_table_link); ld->flags = RETURN_ON_LIST_ERROR; if (CRASHDEBUG(1)) ld->flags |= VERBOSE; hq_open(); cnt = do_list(ld); if (cnt == -1) { error(WARNING, "UNWIND: failed to gather unwind_table list"); return 0; } table_list = (ulong *)GETBUF(cnt * sizeof(ulong)); cnt = retrieve_list(table_list, cnt); hq_close(); if (!(local_unwind_tables = malloc(sizeof(struct local_unwind_table) * cnt))) { error(WARNING, "cannot malloc unwind_table space (%d tables)\n", cnt); FREEBUF(table_list); return 0; } for (i = 0; i < cnt; i++, tp++) { if (!readmem(table_list[i], KVADDR, buf, SIZE(unwind_table), "unwind_table", RETURN_ON_ERROR|QUIET)) { error(WARNING, "cannot read unwind_table\n"); goto failed; } tp = &local_unwind_tables[i]; /* * Copy the required table info for find_table(). */ BCOPY(buf + OFFSET(unwind_table_core), (char *)&tp->core.pc, sizeof(ulong)*2); BCOPY(buf + OFFSET(unwind_table_init), (char *)&tp->init.pc, sizeof(ulong)*2); BCOPY(buf + OFFSET(unwind_table_size), (char *)&tp->size, sizeof(ulong)); /* * Then read the DWARF CFI data. */ vaddr = ULONG(buf + OFFSET(unwind_table_address)); if (!(tp->address = malloc(tp->size))) { error(WARNING, "cannot malloc unwind_table space\n"); goto failed; break; } if (!readmem(vaddr, KVADDR, tp->address, tp->size, "DWARF CFI data", RETURN_ON_ERROR|QUIET)) { error(WARNING, "cannot read unwind_table data\n"); goto failed; } } unwind_tables_cnt = cnt; if (CRASHDEBUG(7)) dump_local_unwind_tables(); failed: FREEBUF(table_list); return unwind_tables_cnt; }
/* * Find the appropriate kernel-only "root_table" unwind_table, * and pass it to populate_local_tables() to do the heavy lifting. */ static int gather_in_memory_unwind_tables(void) { int i, cnt, found; struct syment *sp, *root_tables[10]; char *root_table_buf; char buf[BUFSIZE]; ulong name; STRUCT_SIZE_INIT(unwind_table, "unwind_table"); MEMBER_OFFSET_INIT(unwind_table_core, "unwind_table", "core"); MEMBER_OFFSET_INIT(unwind_table_init, "unwind_table", "init"); MEMBER_OFFSET_INIT(unwind_table_address, "unwind_table", "address"); MEMBER_OFFSET_INIT(unwind_table_size, "unwind_table", "size"); MEMBER_OFFSET_INIT(unwind_table_link, "unwind_table", "link"); MEMBER_OFFSET_INIT(unwind_table_name, "unwind_table", "name"); if (INVALID_SIZE(unwind_table) || INVALID_MEMBER(unwind_table_core) || INVALID_MEMBER(unwind_table_init) || INVALID_MEMBER(unwind_table_address) || INVALID_MEMBER(unwind_table_size) || INVALID_MEMBER(unwind_table_link) || INVALID_MEMBER(unwind_table_name)) { if (CRASHDEBUG(1)) error(NOTE, "unwind_table structure has changed, or does not exist in this kernel\n"); return 0; } /* * Unfortunately there are two kernel root_table symbols. */ if (!(cnt = get_syment_array("root_table", root_tables, 10))) return 0; root_table_buf = GETBUF(SIZE(unwind_table)); for (i = found = 0; i < cnt; i++) { sp = root_tables[i]; if (!readmem(sp->value, KVADDR, root_table_buf, SIZE(unwind_table), "root unwind_table", RETURN_ON_ERROR|QUIET)) goto gather_failed; name = ULONG(root_table_buf + OFFSET(unwind_table_name)); if (read_string(name, buf, strlen("kernel")+1) && STREQ("kernel", buf)) { found++; if (CRASHDEBUG(1)) fprintf(fp, "root_table name: %lx [%s]\n", name, buf); break; } } if (!found) goto gather_failed; cnt = populate_local_tables(sp->value, root_table_buf); FREEBUF(root_table_buf); return cnt; gather_failed: FREEBUF(root_table_buf); return 0; }
/* * Just pass in an unused filename. */ void cmd_snap(void) { int c, fd, n; physaddr_t paddr; size_t offset; char *buf; char *filename; struct node_table *nt; int type; char *elf_header; Elf64_Phdr *load; int load_index; if (!supported) error(FATAL, "command not supported on the %s architecture\n", pc->machine_type); filename = NULL; buf = GETBUF(PAGESIZE()); type = KDUMP_ELF64; while ((c = getopt(argcnt, args, "n")) != EOF) { switch(c) { case 'n': if (machine_type("X86_64")) option_not_supported('n'); else type = NETDUMP_ELF64; break; default: argerrs++; break; } } if (argerrs || !args[optind]) cmd_usage(pc->curcmd, SYNOPSIS); while (args[optind]) { if (filename) cmd_usage(pc->curcmd, SYNOPSIS); if (file_exists(args[optind], NULL)) error(FATAL, "%s: file already exists\n", args[optind]); else if ((fd = open(args[optind], O_RDWR|O_CREAT, 0644)) < 0) error(FATAL, args[optind]); filename = args[optind]; optind++; } if (!filename) cmd_usage(pc->curcmd, SYNOPSIS); init_ram_segments(); if (!(elf_header = generate_elf_header(type, fd, filename))) error(FATAL, "cannot generate ELF header\n"); load = (Elf64_Phdr *)(elf_header + sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr)); load_index = machine_type("X86_64") || machine_type("IA64") ? 1 : 0; for (n = 0; n < vt->numnodes; n++) { nt = &vt->node_table[n]; paddr = nt->start_paddr; offset = load[load_index + n].p_offset; for (c = 0; c < nt->size; c++, paddr += PAGESIZE()) { if (!verify_paddr(paddr)) continue; if (!readmem(paddr, PHYSADDR, &buf[0], PAGESIZE(), "memory page", QUIET|RETURN_ON_ERROR)) continue; lseek(fd, (off_t)(paddr + offset - nt->start_paddr), SEEK_SET); if (write(fd, &buf[0], PAGESIZE()) != PAGESIZE()) error(FATAL, "write to dumpfile failed\n"); if (!print_progress(filename, BTOP(paddr))) return; } } fprintf(stderr, "\r%s: [100%%] ", filename); fprintf(fp, "\n"); sprintf(buf, "/bin/ls -l %s\n", filename); system(buf); FREEBUF(elf_header); FREEBUF(buf); }