/* * Start printing a structure. In general, the function copies the contents of * the structure of size 'size' from the traced process at 'addr' into the * local 'ptr' structure, opens a nested block with name 'name' (which may * be NULL) using an opening bracket, and returns TRUE to indicate that the * caller should print fields from the structure. However, if 'flags' contains * PF_FAILED, the structure will be printed as a pointer, no copy will be made, * and the call will return FALSE. Similarly, if the remote copy fails, a * pointer will be printed and the call will return FALSE. If PF_LOCADDR is * given, 'addr' is a local address, and an intraprocess copy will be made. */ int put_open_struct(struct trace_proc * proc, const char * name, int flags, vir_bytes addr, void * ptr, size_t size) { if ((flags & PF_FAILED) || valuesonly > 1 || addr == 0) { if (flags & PF_LOCADDR) put_field(proc, name, "&.."); else put_ptr(proc, name, addr); return FALSE; } if (!(flags & PF_LOCADDR)) { if (mem_get_data(proc->pid, addr, ptr, size) < 0) { put_ptr(proc, name, addr); return FALSE; } } else memcpy(ptr, (void *) addr, size); put_open(proc, name, flags, "{", ", "); return TRUE; }
/** * \brief Reads a 'concord.ind' file and returns a fifo list of all matches found and their replacement * * \param[in] concord_file_name the name of the concord.ind file * * \return a fifo list of all the matches found with their replacement sentences. Each element is * stored in a locate_pos structure */ struct fifo *read_concord_file(const char *concord_file_name,int mask_encoding_compatibility_input){ unichar line[4096]; struct fifo *f = new_fifo(); U_FILE *concord_desc_file; concord_desc_file = u_fopen_existing_versatile_encoding(mask_encoding_compatibility_input, concord_file_name,U_READ); if( concord_desc_file == NULL){ perror("u_fopen\n"); fprintf(stderr,"Cannot open file %s\n",concord_file_name); exit(1); } if(u_fgets(line,4096,concord_desc_file)==EOF){ fatal_error("Malformed concordance file %s",concord_file_name); } while(u_fgets(line,4096,concord_desc_file)!=EOF){ // we don't want the end of line char line[u_strlen(line)-1]='\0'; locate_pos *l = read_concord_line(line); put_ptr(f,l); } u_fclose(concord_desc_file); return f; }
static int vm_brk_out(struct trace_proc * proc, const message * m_out) { put_ptr(proc, "addr", (vir_bytes)m_out->m_lc_vm_brk.addr); return CT_DONE; }
static int vm_mmap_out(struct trace_proc * proc, const message * m_out) { if (m_out->m_mmap.flags & MAP_THIRDPARTY) put_endpoint(proc, "forwhom", m_out->m_mmap.forwhom); put_ptr(proc, "addr", (vir_bytes)m_out->m_mmap.addr); put_value(proc, "len", "%zu", m_out->m_mmap.len); put_flags(proc, "prot", mmap_prot, COUNT(mmap_prot), "0x%x", m_out->m_mmap.prot); put_flags(proc, "flags", mmap_flags, COUNT(mmap_flags), "0x%x", m_out->m_mmap.flags); put_fd(proc, "fd", m_out->m_mmap.fd); put_value(proc, "offset", "%"PRId64, m_out->m_mmap.offset); return CT_DONE; }
int char_ioctl_arg(struct trace_proc * proc, unsigned long req, void * ptr, int dir) { minix_i2c_ioctl_exec_t *iie; struct fb_var_screeninfo *fbvs; struct volume_level *level; struct inout_ctrl *inout; struct termios *tc; struct ptmget *pm; struct winsize *ws; struct kio_bell *bell; struct kio_leds *leds; struct pciio_cfgreg *pci_cfgreg; struct pciio_bdf_cfgreg *pci_bdf_cfgreg; struct pciio_businfo *pci_businfo; struct pciio_map *pci_iomap; struct pciio_acl *pci_acl; switch (req) { case MINIX_I2C_IOCTL_EXEC: if ((iie = (minix_i2c_ioctl_exec_t *)ptr) == NULL) return IF_OUT; /* we print only the request for now */ put_i2c_op(proc, "iie_op", iie->iie_op); put_value(proc, "iie_addr", "0x%04x", iie->iie_addr); return 0; /* TODO: print command/data/result */ case FBIOGET_VSCREENINFO: if ((fbvs = (struct fb_var_screeninfo *)ptr) == NULL) return IF_IN; put_value(proc, "xres", "%"PRIu32, fbvs->xres); put_value(proc, "yres", "%"PRIu32, fbvs->yres); put_value(proc, "xres_virtual", "%"PRIu32, fbvs->xres_virtual); put_value(proc, "yres_virtual", "%"PRIu32, fbvs->yres_virtual); put_value(proc, "xoffset", "%"PRIu32, fbvs->xoffset); put_value(proc, "yoffset", "%"PRIu32, fbvs->yoffset); put_value(proc, "bits_per_pixel", "%"PRIu32, fbvs->bits_per_pixel); return 0; case FBIOPUT_VSCREENINFO: case FBIOPAN_DISPLAY: if ((fbvs = (struct fb_var_screeninfo *)ptr) == NULL) return IF_OUT; put_value(proc, "xoffset", "%"PRIu32, fbvs->xoffset); put_value(proc, "yoffset", "%"PRIu32, fbvs->yoffset); return 0; case DSPIORATE: case DSPIOSTEREO: case DSPIOSIZE: case DSPIOBITS: case DSPIOSIGN: case DSPIOMAX: case DSPIOFREEBUF: case DSPIOSAMPLESINBUF: if (ptr == NULL) return dir; put_value(proc, NULL, "%u", *(unsigned int *)ptr); return IF_ALL; case MIXIOGETVOLUME: if ((level = (struct volume_level *)ptr) == NULL) return dir; if (dir == IF_OUT) put_sound_device(proc, "device", level->device); else { put_value(proc, "left", "%d", level->left); put_value(proc, "right", "%d", level->right); } return IF_ALL; case MIXIOSETVOLUME: /* Print the corrected volume levels only with verbosity on. */ if ((level = (struct volume_level *)ptr) == NULL) return IF_OUT | ((verbose > 0) ? IF_IN : 0); if (dir == IF_OUT) put_sound_device(proc, "device", level->device); put_value(proc, "left", "%d", level->left); put_value(proc, "right", "%d", level->right); return IF_ALL; case MIXIOGETINPUTLEFT: case MIXIOGETINPUTRIGHT: case MIXIOGETOUTPUT: if ((inout = (struct inout_ctrl *)ptr) == NULL) return dir; if (dir == IF_OUT) put_sound_device(proc, "device", inout->device); else { put_sound_state(proc, "left", inout->left); put_sound_state(proc, "right", inout->right); } return IF_ALL; case MIXIOSETINPUTLEFT: case MIXIOSETINPUTRIGHT: case MIXIOSETOUTPUT: if ((inout = (struct inout_ctrl *)ptr) == NULL) return IF_OUT; put_sound_device(proc, "device", inout->device); put_sound_state(proc, "left", inout->left); put_sound_state(proc, "right", inout->right); return IF_ALL; case TIOCFLUSH: if (ptr == NULL) return IF_OUT; put_flags(proc, NULL, flush_flags, COUNT(flush_flags), "0x%x", *(int *)ptr); return IF_ALL; case TIOCGETA: case TIOCSETA: case TIOCSETAW: case TIOCSETAF: if ((tc = (struct termios *)ptr) == NULL) return dir; /* * These are fairly common IOCTLs, so printing everything by * default would create a lot of noise. By default we limit * ourselves to printing the field that contains what I * consider to be the most important flag: ICANON. * TODO: see if we can come up with a decent format for * selectively printing (relatively important) flags. */ if (verbose > 0) { put_flags(proc, "c_iflag", tc_iflags, COUNT(tc_iflags), "0x%x", tc->c_iflag); put_flags(proc, "c_oflag", tc_oflags, COUNT(tc_oflags), "0x%x", tc->c_oflag); put_flags(proc, "c_cflag", tc_cflags, COUNT(tc_cflags), "0x%x", tc->c_cflag); } put_flags(proc, "c_lflag", tc_lflags, COUNT(tc_lflags), "0x%x", tc->c_lflag); if (verbose > 0) { put_value(proc, "c_ispeed", "%d", tc->c_ispeed); put_value(proc, "c_ospeed", "%d", tc->c_ospeed); } return 0; /* TODO: print the c_cc fields */ case TIOCGETD: case TIOCSETD: if (ptr == NULL) return dir; put_tty_disc(proc, NULL, *(int *)ptr); return IF_ALL; case TIOCGLINED: case TIOCSLINED: if (ptr == NULL) return dir; put_buf(proc, NULL, PF_LOCADDR | PF_STRING, (vir_bytes)ptr, sizeof(linedn_t)); return IF_ALL; case TIOCGPGRP: case TIOCSPGRP: case TIOCOUTQ: case TIOCPKT: case TIOCREMOTE: case TIOCUCNTL: case TIOCSTAT: /* argument seems unused? */ case TIOCGSID: case TIOCCONS: /* argument seems unused? */ case TIOCEXT: case TIOCSQSIZE: case TIOCGQSIZE: /* Print a simple integer. */ if (ptr == NULL) return dir; put_value(proc, NULL, "%d", *(int *)ptr); return IF_ALL; case TIOCPTSNAME: if ((pm = (struct ptmget *)ptr) == NULL) return IF_IN; put_buf(proc, "sn", PF_LOCADDR | PF_STRING, (vir_bytes)pm->sn, sizeof(pm->sn)); return IF_ALL; case TIOCSTI: if (ptr == NULL) return dir; if (!valuesonly) put_value(proc, NULL, "'%s'", get_escape(*(char *)ptr)); else put_value(proc, NULL, "%u", *(char *)ptr); return IF_ALL; case TIOCGWINSZ: case TIOCSWINSZ: if ((ws = (struct winsize *)ptr) == NULL) return dir; /* This is a stupid order, but we follow the struct layout. */ put_value(proc, "ws_row", "%u", ws->ws_row); put_value(proc, "ws_col", "%u", ws->ws_col); if (verbose > 0) { put_value(proc, "ws_xpixel", "%u", ws->ws_xpixel); put_value(proc, "ws_ypixel", "%u", ws->ws_ypixel); } return (verbose > 0) ? IF_ALL : 0; case KIOCBELL: if ((bell = (struct kio_bell *)ptr) == NULL) return IF_OUT; put_value(proc, "kb_pitch", "%u", bell->kb_pitch); put_value(proc, "kb_volume", "%lu", bell->kb_volume); put_struct_timeval(proc, "kb_duration", PF_LOCADDR, (vir_bytes)&bell->kb_duration); return IF_ALL; case KIOCSLEDS: if ((leds = (struct kio_leds *)ptr) == NULL) return IF_OUT; put_flags(proc, "kl_bits", kbd_leds, COUNT(kbd_leds), "0x%x", leds->kl_bits); return IF_ALL; case PCI_IOC_CFGREAD: if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL) return IF_IN; put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg); put_value(proc, "val", "%08x", pci_cfgreg->val); return IF_ALL; case PCI_IOC_CFGWRITE: if ((pci_cfgreg = (struct pciio_cfgreg *)ptr) == NULL) return IF_OUT; put_ptr(proc, "reg", (vir_bytes)pci_cfgreg->reg); put_value(proc, "val", "%08x", pci_cfgreg->val); return IF_ALL; case PCI_IOC_BDF_CFGREAD: if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL) return IF_IN; put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus); put_value(proc, "device", "%u", pci_bdf_cfgreg->device); put_value(proc, "function", "%u", pci_bdf_cfgreg->function); put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg); put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val); return IF_ALL; case PCI_IOC_BDF_CFGWRITE: if ((pci_bdf_cfgreg = (struct pciio_bdf_cfgreg *)ptr) == NULL) return IF_OUT; put_value(proc, "bus", "%u", pci_bdf_cfgreg->bus); put_value(proc, "device", "%u", pci_bdf_cfgreg->device); put_value(proc, "function", "%u", pci_bdf_cfgreg->function); put_ptr(proc, "cfgreg.reg", (vir_bytes)pci_bdf_cfgreg->cfgreg.reg); put_value(proc, "cfgreg.val", "%08x", pci_bdf_cfgreg->cfgreg.val); return IF_ALL; case PCI_IOC_BUSINFO: if ((pci_businfo = (struct pciio_businfo *)ptr) == NULL) return IF_IN; put_value(proc, "busno", "%u", pci_businfo->busno); put_value(proc, "maxdevs", "%u", pci_businfo->maxdevs); return IF_ALL; case PCI_IOC_MAP: if ((pci_iomap = (struct pciio_map *)ptr) == NULL) return IF_OUT|IF_IN; put_value(proc, "flags", "%x", pci_iomap->flags); put_value(proc, "phys_offset", "%08x", pci_iomap->phys_offset); put_value(proc, "size", "%zu", pci_iomap->size); put_value(proc, "readonly", "%x", pci_iomap->readonly); if (IF_IN == dir) put_ptr(proc, "vaddr_ret", (vir_bytes)pci_iomap->vaddr_ret); return IF_ALL; case PCI_IOC_UNMAP: if ((pci_iomap = (struct pciio_map *)ptr) == NULL) return IF_OUT; put_ptr(proc, "vaddr", (vir_bytes)pci_iomap->vaddr); return IF_ALL; case PCI_IOC_RESERVE: if ((pci_acl = (struct pciio_acl *)ptr) == NULL) return IF_OUT; put_value(proc, "domain", "%u", pci_acl->domain); put_value(proc, "bus", "%u", pci_acl->bus); put_value(proc, "device", "%u", pci_acl->device); put_value(proc, "function", "%u", pci_acl->function); return IF_ALL; case PCI_IOC_RELEASE: if ((pci_acl = (struct pciio_acl *)ptr) == NULL) return IF_OUT; put_value(proc, "domain", "%u", pci_acl->domain); put_value(proc, "bus", "%u", pci_acl->bus); put_value(proc, "device", "%u", pci_acl->device); put_value(proc, "function", "%u", pci_acl->function); return IF_ALL; default: return 0; } }
/* * Print the contents of a buffer, at remote address 'addr' and of 'bytes' * size, as a field using name 'name' (which may be NULL). If the PF_FAILED * flag is given, the buffer address is printed instead, since it is assumed * that the actual buffer contains garbage. If the PF_LOCADDR flag is given, * the given address is a local address and no intraprocess copies are * performed. If the PF_STRING flag is given, the buffer is expected to * contain a null terminator within its size, and the string will be printed * only up to there. Normally, the string is cut off beyond a number of bytes * which depends on the verbosity level; if the PF_FULL flag is given, the full * string will be printed no matter its size (used mainly for path names, which * typically become useless once cut off). */ void put_buf(struct trace_proc * proc, const char * name, int flags, vir_bytes addr, ssize_t size) { const char *escaped; size_t len, off, max, chunk; int i, cutoff; char *p; if ((flags & PF_FAILED) || valuesonly || addr == 0 || size < 0) { if (flags & PF_LOCADDR) put_field(proc, name, "&.."); else put_ptr(proc, name, addr); return; } if (size == 0) { put_field(proc, name, "\"\""); return; } /* * TODO: the maximum says nothing about the size of the printed text. * Escaped-character printing can make the output much longer. Does it * make more sense to apply a limit after the escape transformation? */ if (verbose == 0) max = 32; else if (verbose == 1) max = 256; else max = SIZE_MAX; /* * If the output is cut off, we put two dots after the closing quote. * For non-string buffers, the output is cut off if the size exceeds * our limit or we run into a copying error somewhere in the middle. * For strings, the output is cut off unless we find a null terminator. */ cutoff = !!(flags & PF_STRING); len = (size_t)size; if (!(flags & PF_FULL) && len > max) { len = max; cutoff = TRUE; } for (off = 0; off < len; off += chunk) { chunk = len - off; if (chunk > sizeof(formatbuf) - 1) chunk = sizeof(formatbuf) - 1; if (!(flags & PF_LOCADDR)) { if (mem_get_data(proc->pid, addr + off, formatbuf, chunk) < 0) { if (off == 0) { put_ptr(proc, name, addr); return; } cutoff = TRUE; break; } } else memcpy(formatbuf, (void *)addr, chunk); if (off == 0) put_field(proc, name, "\""); /* In strings, look for the terminating null character. */ if ((flags & PF_STRING) && (p = memchr(formatbuf, '\0', chunk)) != NULL) { chunk = (size_t)(p - formatbuf); cutoff = FALSE; } /* Print the buffer contents using escaped characters. */ for (i = 0; i < chunk; i++) { escaped = get_escape(formatbuf[i]); put_text(proc, escaped); } /* Stop if we found the end of the string. */ if ((flags & PF_STRING) && !cutoff) break; } if (cutoff) put_text(proc, "\".."); else put_text(proc, "\""); }