Ejemplo n.º 1
0
/*
 * Actual dumper
 *
 * This is a two-pass process; first we find the offsets of the bits,
 * and then they are actually written out.  If we run out of core limit
 * we just truncate.
 */
static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
{
	int has_dumped = 0;
	mm_segment_t fs;
	int segs;
	size_t size = 0;
	int i;
	struct vm_area_struct *vma;
	struct elfhdr elf;
	off_t offset = 0, dataoff;
	unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
	int numnote = 4;
	struct memelfnote notes[4];
	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
	elf_fpregset_t fpu;		/* NT_PRFPREG */
	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */

	/* first copy the parameters from user space */
	memset(&psinfo, 0, sizeof(psinfo));
	{
		unsigned int i, len;

		len = current->mm->arg_end - current->mm->arg_start;
		if (len >= ELF_PRARGSZ)
			len = ELF_PRARGSZ-1;
		copy_from_user(&psinfo.pr_psargs,
			      (const char *)current->mm->arg_start, len);
		for(i = 0; i < len; i++)
			if (psinfo.pr_psargs[i] == 0)
				psinfo.pr_psargs[i] = ' ';
		psinfo.pr_psargs[len] = 0;

	}

	memset(&prstatus, 0, sizeof(prstatus));
	/*
	 * This transfers the registers from regs into the standard
	 * coredump arrangement, whatever that is.
	 */
#ifdef ELF_CORE_COPY_REGS
	ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
#else
	if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
	{
		printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
			(long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
	}
	else
		*(struct pt_regs *)&prstatus.pr_reg = *regs;
#endif

	/* now stop all vm operations */
	down_write(&current->mm->mmap_sem);
	segs = current->mm->map_count;

#ifdef DEBUG
	printk("elf_core_dump: %d segs %lu limit\n", segs, limit);
#endif

	/* Set up header */
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELF_CLASS;
	elf.e_ident[EI_DATA] = ELF_DATA;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	elf.e_type = ET_CORE;
	elf.e_machine = ELF_ARCH;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
#ifdef ELF_CORE_EFLAGS
	elf.e_flags = ELF_CORE_EFLAGS;
#else
	elf.e_flags = 0;
#endif
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(struct elf_phdr);
	elf.e_phnum = segs+1;		/* Include notes */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	fs = get_fs();
	set_fs(KERNEL_DS);

	has_dumped = 1;
	current->flags |= PF_DUMPCORE;

	DUMP_WRITE(&elf, sizeof(elf));
	offset += sizeof(elf);				/* Elf header */
	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers */

	/*
	 * Set up the notes in similar form to SVR4 core dumps made
	 * with info from their /proc.
	 */

	notes[0].name = "CORE";
	notes[0].type = NT_PRSTATUS;
	notes[0].datasz = sizeof(prstatus);
	notes[0].data = &prstatus;
	prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
	prstatus.pr_sigpend = current->pending.signal.sig[0];
	prstatus.pr_sighold = current->blocked.sig[0];
	psinfo.pr_pid = prstatus.pr_pid = current->pid;
	psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
	psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
	psinfo.pr_sid = prstatus.pr_sid = current->session;
	prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
	prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
	prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
	prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
	prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
	prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
	prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
	prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);

#ifdef DEBUG
	dump_regs("Passed in regs", (elf_greg_t *)regs);
	dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
#endif

	notes[1].name = "CORE";
	notes[1].type = NT_PRPSINFO;
	notes[1].datasz = sizeof(psinfo);
	notes[1].data = &psinfo;
	i = current->state ? ffz(~current->state) + 1 : 0;
	psinfo.pr_state = i;
	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
	psinfo.pr_nice = task_nice(current);
	psinfo.pr_flag = current->flags;
	psinfo.pr_uid = NEW_TO_OLD_UID(current->uid);
	psinfo.pr_gid = NEW_TO_OLD_GID(current->gid);
	strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));

	notes[2].name = "CORE";
	notes[2].type = NT_TASKSTRUCT;
	notes[2].datasz = sizeof(*current);
	notes[2].data = current;

	/* Try to dump the FPU. */
	prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
	if (!prstatus.pr_fpvalid)
	{
		numnote--;
	}
	else
	{
		notes[3].name = "CORE";
		notes[3].type = NT_PRFPREG;
		notes[3].datasz = sizeof(fpu);
		notes[3].data = &fpu;
	}
	
	/* Write notes phdr entry */
	{
		struct elf_phdr phdr;
		int sz = 0;

		for(i = 0; i < numnote; i++)
			sz += notesize(&notes[i]);

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	/* Page-align dumped data */
	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);

	/* Write program headers for segments dump */
	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
		struct elf_phdr phdr;
		size_t sz;

		sz = vma->vm_end - vma->vm_start;

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = vma->vm_start;
		phdr.p_paddr = 0;
		phdr.p_filesz = maydump(vma) ? sz : 0;
		phdr.p_memsz = sz;
		offset += phdr.p_filesz;
		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
		if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
		if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
		phdr.p_align = ELF_EXEC_PAGESIZE;

		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	for(i = 0; i < numnote; i++)
		if (!writenote(&notes[i], file))
			goto end_coredump;

	DUMP_SEEK(dataoff);

	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
		unsigned long addr;

		if (!maydump(vma))
			continue;

#ifdef DEBUG
		printk("elf_core_dump: writing %08lx-%08lx\n", vma->vm_start, vma->vm_end);
#endif

		for (addr = vma->vm_start;
		     addr < vma->vm_end;
		     addr += PAGE_SIZE) {
			struct page* page;
			struct vm_area_struct *vma;

			if (get_user_pages(current, current->mm, addr, 1, 0, 1,
						&page, &vma) <= 0) {
				DUMP_SEEK (file->f_pos + PAGE_SIZE);
			} else {
				if (page == ZERO_PAGE(addr)) {
					DUMP_SEEK (file->f_pos + PAGE_SIZE);
				} else {
					void *kaddr;
					flush_cache_page(vma, addr);
					kaddr = kmap(page);
					DUMP_WRITE(kaddr, PAGE_SIZE);
					flush_page_to_ram(page);
					kunmap(page);
				}
				put_page(page);
			}
		}
	}

	if ((off_t) file->f_pos != offset) {
		/* Sanity check */
		printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
		       (off_t) file->f_pos, offset);
	}

 end_coredump:
	set_fs(fs);
	up_write(&current->mm->mmap_sem);
	return has_dumped;
}
Ejemplo n.º 2
0
Archivo: scot.c Proyecto: eddyc/csound
static                          /* reads score{} section */
void readscore(Inst *insttop)
{
    char    s[128];
    Inst   *p;
    Rat     grpmul, timesig, curtime, lastbar, lastnote, rattmp;
    Tempo  *tempotop, *tempop;
    Note   *notetop, *pn, *qn, *ln;
    Nextp  *nextlist, *nextpp;
    int     accidentals,
            octaves,
            vertical, key[PITCHCLASSES], barkey[PITCHCLASSES], transpose, z;
    double  maxtime, fcurtime;

#ifdef DEBUG
    printf("Reading score section\n");
#endif

    maxtime = 0.0;
    if (expectchar('{'))
      scotferror(Str("Syntax error: no {"));
    tempotop = (Tempo *) malloc(sizeof(Tempo));
    tempotop->time.num = 0;
    tempotop->time.denom = 1;
    tempotop->val = 60;
    tempotop->next = NULL;
    for (;;) {
      tempop = tempotop;
      efindword(s);
      if (s[0] == '}')
        break;
      if (s[0] != '$')
        scotferror(Str("No instrument specified"));
      p = insttop;
      while ((p != NULL) && (strcmp(&s[1], p->name)))
        p = p->next;
      if (p == NULL)
        scotferror(Str("Instrument not defined"));
      notetop = ln = NULL;
      grpmul.num = 1;
      grpmul.denom = 1;
      timesig.num = 0;
      timesig.denom = 1;
      curtime.num = 0;
      curtime.denom = 1;
      lastbar.num = 0;
      lastbar.denom = 1;
      lastnote.num = 0;
      lastnote.denom = 1;
      accidentals = octaves = vertical = TRUE;
      for (z = 0; z < PITCHCLASSES; z++)
        key[z] = barkey[z] = 0;
      transpose = 0;
      nextlist = NULL;
      readinstsec(p, &nextlist, &grpmul, &timesig, &curtime,
                  &lastbar, &lastnote, &notetop, &ln, &tempop, &accidentals,
                  &octaves, &vertical, key, barkey, &transpose, "}$");
      for (pn = notetop; pn; pn = pn->next) {
        if (!pn->written) {
          char   *ps, *ps2;

          for (nextpp = nextlist; nextpp; nextpp = nextpp->next) {
            ps = findparam(nextpp->dst, &pn->carryp);
            if (!strcmp(ps, NEXTP)) {
              ps2 = findparam(nextpp->src, &pn->p);
              if (!strcmp(ps2, "."))
                ps2 = findparam(nextpp->src, &pn->carryp);
              strcpy(ps, ps2);
            }
          }
          writenote(pn);
        }
        if (pn->tie)
          scoterror(Str("unresolved tie"));
        if (pn->slur & 1)
          scoterror(Str("unresolved slur"));
        ratadd(&rattmp, &pn->start, &pn->dur);
        if (ratcmp(&rattmp, &curtime) > 0)
          ratass(&curtime, &rattmp);

#ifdef DEBUG
        if (pn == pn->next)
          scotferror(Str("Circular note list\n"));
#endif

      }
      while (nextlist) {
        nextpp = nextlist;
        nextlist = nextlist->next;
        free((char *) nextpp);
      }
      pn = notetop;
      while (pn) {
        qn = pn;
        pn = pn->next;
        freenote(qn);
      }
      fcurtime = ratval(&curtime);
      if (fcurtime > maxtime)
        maxtime = fcurtime;
    }
    tempop = tempotop;
    putc('t', outfile);
    for (;;) {
      tempotop = tempop;
      tempop = tempop->next;
      fprintf(outfile, "%g %d", ratval(&tempotop->time), tempotop->val);
      free((char *) tempotop);
      if (!tempop)
        break;
      putc(' ', outfile);
    }
    fprintf(outfile, "\nf0 %g\ns\n", maxtime);
}
Ejemplo n.º 3
0
/* Actual dumper.
 *
 * This is a two-pass process; first we find the offsets of the bits,
 * and then they are actually written out.  If we run out of core limit
 * we just truncate.
 */
static int irix_core_dump(long signr, struct pt_regs *regs, struct file *file, unsigned long limit)
{
	int has_dumped = 0;
	mm_segment_t fs;
	int segs;
	int i;
	size_t size;
	struct vm_area_struct *vma;
	struct elfhdr elf;
	off_t offset = 0, dataoff;
	int numnote = 3;
	struct memelfnote notes[3];
	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
	elf_fpregset_t fpu;		/* NT_PRFPREG */
	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */

	/* Count what's needed to dump, up to the limit of coredump size. */
	segs = 0;
	size = 0;
	for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
		if (maydump(vma))
		{
			int sz = vma->vm_end-vma->vm_start;

			if (size+sz >= limit)
				break;
			else
				size += sz;
		}

		segs++;
	}
	pr_debug("irix_core_dump: %d segs taking %d bytes\n", segs, size);

	/* Set up header. */
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELFCLASS32;
	elf.e_ident[EI_DATA] = ELFDATA2LSB;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
	elf.e_ident[EI_OSABI] = ELF_OSABI;
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	elf.e_type = ET_CORE;
	elf.e_machine = ELF_ARCH;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
	elf.e_flags = 0;
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(struct elf_phdr);
	elf.e_phnum = segs+1;		/* Include notes. */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	fs = get_fs();
	set_fs(KERNEL_DS);

	has_dumped = 1;
	current->flags |= PF_DUMPCORE;

	DUMP_WRITE(&elf, sizeof(elf));
	offset += sizeof(elf);				/* Elf header. */
	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers. */

	/* Set up the notes in similar form to SVR4 core dumps made
	 * with info from their /proc.
	 */
	memset(&psinfo, 0, sizeof(psinfo));
	memset(&prstatus, 0, sizeof(prstatus));

	notes[0].name = "CORE";
	notes[0].type = NT_PRSTATUS;
	notes[0].datasz = sizeof(prstatus);
	notes[0].data = &prstatus;
	prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
	prstatus.pr_sigpend = current->pending.signal.sig[0];
	prstatus.pr_sighold = current->blocked.sig[0];
	psinfo.pr_pid = prstatus.pr_pid = task_pid_vnr(current);
	psinfo.pr_ppid = prstatus.pr_ppid = task_pid_vnr(current->parent);
	psinfo.pr_pgrp = prstatus.pr_pgrp = task_pgrp_vnr(current);
	psinfo.pr_sid = prstatus.pr_sid = task_session_vnr(current);
	if (thread_group_leader(current)) {
		/*
		 * This is the record for the group leader.  Add in the
		 * cumulative times of previous dead threads.  This total
		 * won't include the time of each live thread whose state
		 * is included in the core dump.  The final total reported
		 * to our parent process when it calls wait4 will include
		 * those sums as well as the little bit more time it takes
		 * this and each other thread to finish dying after the
		 * core dump synchronization phase.
		 */
		jiffies_to_timeval(current->utime + current->signal->utime,
		                   &prstatus.pr_utime);
		jiffies_to_timeval(current->stime + current->signal->stime,
		                   &prstatus.pr_stime);
	} else {
		jiffies_to_timeval(current->utime, &prstatus.pr_utime);
		jiffies_to_timeval(current->stime, &prstatus.pr_stime);
	}
	jiffies_to_timeval(current->signal->cutime, &prstatus.pr_cutime);
	jiffies_to_timeval(current->signal->cstime, &prstatus.pr_cstime);

	if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) {
		printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) "
		       "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs));
	} else {
		*(struct pt_regs *)&prstatus.pr_reg = *regs;
	}

	notes[1].name = "CORE";
	notes[1].type = NT_PRPSINFO;
	notes[1].datasz = sizeof(psinfo);
	notes[1].data = &psinfo;
	i = current->state ? ffz(~current->state) + 1 : 0;
	psinfo.pr_state = i;
	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
	psinfo.pr_nice = task_nice(current);
	psinfo.pr_flag = current->flags;
	psinfo.pr_uid = current->uid;
	psinfo.pr_gid = current->gid;
	{
		int i, len;

		set_fs(fs);

		len = current->mm->arg_end - current->mm->arg_start;
		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
		(void *) copy_from_user(&psinfo.pr_psargs,
			       (const char __user *)current->mm->arg_start, len);
		for (i = 0; i < len; i++)
			if (psinfo.pr_psargs[i] == 0)
				psinfo.pr_psargs[i] = ' ';
		psinfo.pr_psargs[len] = 0;

		set_fs(KERNEL_DS);
	}
	strlcpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));

	/* Try to dump the FPU. */
	prstatus.pr_fpvalid = dump_fpu(regs, &fpu);
	if (!prstatus.pr_fpvalid) {
		numnote--;
	} else {
		notes[2].name = "CORE";
		notes[2].type = NT_PRFPREG;
		notes[2].datasz = sizeof(fpu);
		notes[2].data = &fpu;
	}

	/* Write notes phdr entry. */
	{
		struct elf_phdr phdr;
		int sz = 0;

		for (i = 0; i < numnote; i++)
			sz += notesize(&notes[i]);

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	/* Page-align dumped data. */
	dataoff = offset = roundup(offset, PAGE_SIZE);

	/* Write program headers for segments dump. */
	for (vma = current->mm->mmap, i = 0;
		i < segs && vma != NULL; vma = vma->vm_next) {
		struct elf_phdr phdr;
		size_t sz;

		i++;

		sz = vma->vm_end - vma->vm_start;

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = vma->vm_start;
		phdr.p_paddr = 0;
		phdr.p_filesz = maydump(vma) ? sz : 0;
		phdr.p_memsz = sz;
		offset += phdr.p_filesz;
		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
		if (vma->vm_flags & VM_WRITE)
			phdr.p_flags |= PF_W;
		if (vma->vm_flags & VM_EXEC)
			phdr.p_flags |= PF_X;
		phdr.p_align = PAGE_SIZE;

		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	for (i = 0; i < numnote; i++)
		if (!writenote(&notes[i], file))
			goto end_coredump;

	set_fs(fs);

	DUMP_SEEK(dataoff);

	for (i = 0, vma = current->mm->mmap;
	    i < segs && vma != NULL;
	    vma = vma->vm_next) {
		unsigned long addr = vma->vm_start;
		unsigned long len = vma->vm_end - vma->vm_start;

		if (!maydump(vma))
			continue;
		i++;
		pr_debug("elf_core_dump: writing %08lx %lx\n", addr, len);
		DUMP_WRITE((void __user *)addr, len);
	}

	if ((off_t) file->f_pos != offset) {
		/* Sanity check. */
		printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
		       (off_t) file->f_pos, offset);
	}

end_coredump:
	set_fs(fs);
	return has_dumped;
}
Ejemplo n.º 4
0
Archivo: scot.c Proyecto: eddyc/csound
static                          /* reads from one $instrument to the next */
void readinstsec(Inst *inst,
                 Nextp **nextlist,
                 Rat *grpmul,
                 Rat *timesig,
                 Rat *curtime,
                 Rat *lastbar,
                 Rat *lastnote,
                 Note **notetop,
                 Note **ln,
                 Tempo **tempop,
                 int *accidentals,
                 int *octaves,
                 int *vertical,
                 int *key, int *barkey, int *transpose, char *endchar)
{
    static Rat durdiv = { 4L, 1L };

    int     c, z, lastpitchclass;
    char    s[128], *sp;
    Rat     ratstack, rattmp;
    Note   *pn, *nn, *pn2 = NULL;
    Strlist *ps;
    Nextp  *nextpp;

#ifdef DEBUG
    printf("Reading instrument section: %s\n", inst->name);
#endif

    pn = (*notetop);
    for (;;) {
      findchar(&c);
      if (strchr(endchar, c))
        break;

#ifdef DEBUG
      printf("Processing char: %c\n", c);
#endif

      switch (c) {
      case 't':
        if (findint(&c)) {
          scoterror(Str("Tempo must be specified"));
          break;
        }
        if ((*tempop)->next) {
          scoterror(Str("Redefinition of tempo"));
          break;
        }
        (*tempop)->next = (Tempo *) malloc(sizeof(Tempo));
        *tempop = (*tempop)->next;
        (*tempop)->next = NULL;
        ratass(&((*tempop)->time), curtime);
        (*tempop)->val = c;
        break;
      case '!':
        efindword(s);
        if ((c = strlen(s)) < 2)
          scoterror(Str("Must specify 2 or more letters of keyword"));
        if (!strncmp(s, "accidentals", c)) {
          if (findonoff(accidentals))
            scoterror(Str("Must be \"on\" or \"off\""));

#ifdef DEBUG
          printf(" accidentals %s\n", accidentals ? "on" : "off");
#endif

        }
        else if (!strncmp(s, "octaves", c)) {
          if (findonoff(octaves))
            scoterror(Str("Must be \"on\" or \"off\""));

#ifdef DEBUG
          printf(" ocatves %s\n", *octaves ? "on" : "off");
#endif

        }
        else if (!strncmp(s, "vertical", c)) {
          if (findonoff(vertical))
            scoterror(Str("Must be \"on\" or \"off\""));

#ifdef DEBUG
          printf(" vertical %s\n", *vertical ? "on" : "off");
#endif

        }
        else if (!strncmp(s, "timesignature", c)) {
          efindword(s);

          if ((sscanf(s, "%lu/%lu", &timesig->num, &timesig->denom) != 2)
              ||
              (&(timesig->denom) == 0) ) {
            scoterror(Str("Invalid time signature"));
            timesig->num = 0;
            timesig->denom = 1;
          }

#ifdef DEBUG
          printf(" time sig=%lu/%lu\n", timesig->num, timesig->denom);
#endif

          ratstack.num = 4;
          ratstack.denom = 1;
          ratmul(timesig, timesig, &ratstack);

#ifdef DEBUG
          printf(" measure length=%f\n", ratval(timesig));
#endif

        }
        else if (!strncmp(s, "key", c)) {
          int     y;

          efindword(s);
          for (z = 0; z < PITCHCLASSES; z++)
            key[z] = 0;
          c = y = 0;
          for (z = 0; s[z] != (char) 0; z++)
            switch ((int) s[z]) {
            case '#':
              c = y + 1;
              y++;
              break;
            case '-':
              c = y - 1;
              y--;
              break;
            default:
              if (!isalpha(s[z]))
                scoterror(Str("Bad key signature"));
              key[letterval((int) s[z])] = c;
              y = 0;
            }
          for (z = 0; z < PITCHCLASSES; z++)
            barkey[z] = key[z];
        }
        else if (!strncmp(s, "transpose", c)) {
          efindword(s);
          *transpose = 0;
          for (z = 0; s[z]; z++) {
            switch (s[z]) {
            case ',':
              (*transpose) -= NOTESPEROCT;
              break;
            case '\'':
              (*transpose) += NOTESPEROCT;
              break;
            case '=':
              (*transpose) = 0;
              break;
            case '#':
              (*transpose)++;
              break;
            case '-':
              (*transpose)--;
              break;
            default:
              (*transpose) += naturals[letterval((int) s[z])];
            }
          }
        }
        else if (!strncmp(s, "next", c)) {
          efindword(s);
          if (sscanf(s, "p%d", &c) != 1) {
            scoterror(Str("Invalid field"));
            efindword(s);
            break;
          }
          efindword(s);
          if (sscanf(s, "p%d", &z) != 1) {
            scoterror(Str("Invalid field"));
            break;
          }
          if (*nextlist == NULL) {
            *nextlist = (Nextp *) malloc(sizeof(Nextp));
            nextpp = (*nextlist);
            nextpp->next = NULL;
          }
          else {
            nextpp = (*nextlist);
            if ((c == nextpp->dst) || (z == nextpp->src))
              scoterror(Str("Nested next-parameter passing"));
            while (nextpp->next) {
              nextpp = nextpp->next;
              if ((c == nextpp->dst) || (z == nextpp->src))
                scoterror(Str("Nested next-parameter passing"));
            }
            nextpp->next = (Nextp *) malloc(sizeof(Nextp));
            nextpp = nextpp->next;
            nextpp->next = NULL;
          }
          nextpp->src = c;
          nextpp->dst = z;
        }
        else
          scoterror(Str("Unrecognised keyword"));
        break;
      case '{':
        findint(&c);
        expectchar(':');
        if (!c) {
          ratstack.num = 2L;
          ratstack.denom = 3L;
        }
        else {
          ratstack.denom = (unsigned long) c;
          findint(&c);
          if (!c) {
            for (z = 1; (unsigned long) z < ratstack.denom; z *= 2);
            z /= 2;
            ratstack.num = (unsigned long) z;
          }
          else
            ratstack.num = (unsigned long) c;
          expectchar(':');
        }
        ratmul(grpmul, grpmul, &ratstack);
        readinstsec(inst, nextlist, grpmul, timesig, curtime,
                    lastbar, lastnote, notetop, ln, tempop, accidentals,
                    octaves, vertical, key, barkey, transpose, ":");
        ratdiv(grpmul, grpmul, &ratstack);
        expectchar(':');
        expectchar('}');
        break;
      case '(':
        ratass(&ratstack, curtime);
        if (pn == (*notetop)) {
          readinstsec(inst, nextlist, grpmul, timesig, curtime,
                      lastbar, lastnote, notetop, ln, tempop, accidentals,
                      octaves, vertical, key, barkey, transpose, ")");
          pn = (*notetop);
        }
        else {
          readinstsec(inst, nextlist, grpmul, timesig, curtime,
                      lastbar, lastnote, &pn2->next, ln, tempop, accidentals,
                      octaves, vertical, key, barkey, transpose, ")");
          pn = pn2->next;
        }
        expectchar(')');
        ratass(lastnote, &ratstack);
        break;
      case '/':
        ratadd(lastbar, lastbar, timesig);
        if ((timesig->num) && (ratcmp(lastbar, curtime))) {
          scoterror(Str("Wrong number of beats in bar"));
          ratass(lastbar, curtime);
        }
        for (z = 0; z < PITCHCLASSES; z++)
          barkey[z] = key[z];
        break;
      case '<':
        if (pn == NULL) {
          scoterror(Str("Syntax error: cannot back up"));
          break;
        }
        if (pn->next == NULL) {
          pn->next = (Note *) malloc(sizeof(Note));
          initnote(pn->next);
          pn->next->instrum = pn->instrum + 0.01;
        }
        pn2 = pn;
        pn = pn->next;
        ratass(curtime, lastnote);
        break;
      default:

#ifdef DEBUG
        printf("Reading note\n");
        printf(" time=%lu/%lu\n", curtime->num, curtime->denom);
        printf(" =%f\n", ratval(curtime));
#endif

        scotungetc();
        nn = (Note *) malloc(sizeof(Note));
        nn->p = NULL;
        nn->written = FALSE;
        if (*notetop == NULL) {
          pn = (*ln) = (*notetop) = (Note *) malloc(sizeof(Note));
          initnote(*notetop);
          (*notetop)->instrum = (double) inst->number + 0.01;
        }
        else if (ratcmp(curtime, lastnote))
          pn = (*notetop);
        nn->instrum = pn->instrum;

#ifdef DEBUG
        printf(" instrument #%f\n", nn->instrum);
#endif

        if (*vertical)
          strlistcopy(&nn->carryp, &(*ln)->carryp);
        else
          strlistcopy(&nn->carryp, &pn->carryp);
        for (nextpp = (*nextlist); nextpp; nextpp = nextpp->next) {
          sp = findparam(nextpp->dst, &nn->carryp);
          if (!strcmp(sp, "."))
            strcpy(sp, NEXTP);
        }
        ratass(&nn->start, curtime);
        if (!findint(&c)) {
          ratstack.num = (unsigned long) c;
          ratstack.denom = 1L;
          ratdiv(&nn->dur, &durdiv, &ratstack);
          ratass(&ratstack, &nn->dur);
          rattmp.num = 1L;
          rattmp.denom = 2L;
          for (;;) {
            findchar(&c);
            if (c != '.')
              break;
            ratmul(&ratstack, &ratstack, &rattmp);
            ratadd(&nn->dur, &nn->dur, &ratstack);
          }
        }
        else {
          if (*vertical)
            ratass(&nn->dur, &((*ln)->lastdur));
          else
            ratass(&nn->dur, &pn->lastdur);
          findchar(&c);
        }
        ratass(&nn->lastdur, &nn->dur);
        ratmul(&nn->dur, &nn->dur, grpmul);

#ifdef DEBUG
        printf(" duration=%f\n", ratval(&nn->dur));
        printf(" c=%c\n", c);
#endif

        if (c == '=') {
          nn->octave = 8;
          lastpitchclass = 0;
        }
        else {
          nn->octave = pn->octave;
          lastpitchclass = pn->pitchclass;
          scotungetc();
        }
        for (;;) {
          findchar(&c);
          if (c == '\'')
            nn->octave++;
          else if (c == ',')
            nn->octave--;
          else
            break;
        }
        if (c == 'r') {
          ratass(lastnote, curtime);
          ratmul(&rattmp, &nn->lastdur, grpmul);
          ratadd(curtime, curtime, &rattmp);
          ratass(&(*ln)->lastdur, &nn->lastdur);
          ratass(&pn->lastdur, &nn->lastdur);
          freenote(nn);
          break;
        }
        else {
          nn->pitchclass = letterval(c);
          if (*octaves) {
            c = nn->pitchclass - lastpitchclass;
            if (c < -(PITCHCLASSES / 2))
              nn->octave++;
            else if (c > PITCHCLASSES / 2)
              nn->octave--;
          }
        }
        nn->accid = 0;
        nn->accmod = FALSE;
        for (;;) {
          findchar(&c);
          if (c == '#') {
            nn->accid++;
            nn->accmod = TRUE;
          }
          else if (c == '-') {
            nn->accid--;
            nn->accmod = TRUE;
          }
          else if (c == 'n') {
            nn->accid = 0;
            nn->accmod = TRUE;
          }
          else
            break;
        }
        if (!nn->accmod)
          nn->accid = barkey[nn->pitchclass];
        else if (*accidentals)
          barkey[nn->pitchclass] = nn->accid;

#ifdef DEBUG
        printf(" transpose=%d\n", *transpose);
        printf(" octave=%d pitchclass=%d accid=%d transpose=%d pitch=%f\n",
               nn->octave, nn->pitchclass, nn->accid, *transpose,
               pitchval(nn->octave, nn->pitchclass, nn->accid, *transpose));
#endif

        if (c == '_') {
          findchar(&c);
          if (c == '_') {
            nn->tie = TRUE;
            nn->slur = 0;
            findchar(&c);
          }
          else {
            nn->slur = 1;
            nn->tie = FALSE;
          }
        }
        else {
          nn->slur = 0;
          nn->tie = FALSE;
        }
        if (pn->slur & 1)
          nn->slur += 2;

#ifdef DEBUG
        printf(" slur=%d tie=%d\n", nn->slur, nn->tie);
#endif

        if (pn->tie) {
          ratadd(&rattmp, &pn->start, &pn->dur);
          if (ratcmp(&rattmp, curtime))
            scoterror(Str("Improper tie"));
          if (((nn->octave != pn->octave) ||
               (nn->pitchclass != pn->pitchclass) ||
               ((nn->accid != pn->accid) && (nn->accmod))) &&
              (pitchval(nn->octave, nn->pitchclass, nn->accid, *transpose) !=
               pitchval(pn->octave, pn->pitchclass, pn->accid, *transpose)))
            scoterror(Str("Tie between different pitches"));
          ratadd(&pn->dur, &pn->dur, &nn->dur);
          ratass(&pn->lastdur, &nn->lastdur);
          pn->slur += nn->slur;
          pn->tie = nn->tie;
          freenote(nn);
          nn = pn;
          if (c == (char) '[')
            scoterror(Str("Warning: params changed on tie"));
        }
        else {
          ps = nn->p = (Strlist *) malloc(sizeof(Strlist));
          for (z = 0; z < 4; z++) {
            ps->next = (Strlist *) malloc(sizeof(Strlist));
            ps = ps->next;
          }
          ps->next = NULL;
        }
        ps = nn->p;
        sprintf(ps->str, "%.02f", nn->instrum);
        ps = ps->next;
        sprintf(ps->str, "%g", ratval(&nn->start));
        ps = ps->next;
        sprintf(ps->str, "%g", ratval(&nn->dur));
        ps = ps->next;
        sprintf(ps->str, "%d", nn->slur);
        ps = ps->next;
        sprintf(ps->str, "%.02f",
                pitchval(nn->octave, nn->pitchclass, nn->accid, *transpose));
        if (c == '[') {
          char   *pars;
          int     pnum;

          pars = readparams(inst);

#ifdef DEBUG
          printf("Params: %s\n", pars);
#endif

          z = 0;
          pnum = 6;
          while (strchr(" \t\r\n", (int) pars[z]))
            z++;
          for (;;) {
            if (pars[z] == (char) ']')
              break;
            c = 0;
            while (!strchr(" \t\r\n:]", (int) pars[z]))
              s[c++] = pars[z++];
            s[c] = (char) 0;

#ifdef DEBUG
            printf("Read: %s\n", s);
#endif

            while (strchr(" \t\r\n", (int) pars[z]))
              z++;
            if (pars[z] == (char) ':') {
              pnum = atoi(s);
              if (pnum < 6)
                scoterror(Str("Parameter number out of range"));
              z++;
              while (strchr(" \t\r\n", (int) pars[z]))
                z++;
              continue;
            }

#ifdef DEBUG
            printf("Param #%d: %s\n", pnum, s);
#endif

            if (s[0] == (char) '\'') {
              addparam(pnum, &s[1], &nn->p);
              addparam(pnum, ".", &nn->carryp);
            }
            else {
              addparam(pnum, s, &nn->p);
              addparam(pnum, s, &nn->carryp);
            }
            pnum++;
          }
          free(pars);
        }
        else
          scotungetc();
        if ((nn != pn) && (!pn->written)) {

#ifdef DEBUG
          printf("  doing nextp stuff:\n");
#endif

          for (nextpp = (*nextlist); nextpp; nextpp = nextpp->next) {

#ifdef DEBUG
            printf("   carrying p%d to p%d?\n", nextpp->src, nextpp->dst);
#endif

            if (!strcmp(findparam(nextpp->dst, &pn->carryp), NEXTP)) {
              sp = findparam(nextpp->dst, &pn->p);
              if (!strcmp(sp, ".")) {
                char   *sp2;

                sp2 = findparam(nextpp->src, &nn->p);
                if (!strcmp(sp2, "."))
                  sp2 = findparam(nextpp->src, &nn->carryp);
                strcpy(sp, sp2);

#ifdef DEBUG
                printf("   Yes.\n");
#endif

              }
            }
          }
          writenote(pn);
        }
        if ((!(*nextlist)) && (!nn->tie))
          writenote(nn);
        if (nn != pn) {
          if (!pn->written)
            scoterror(Str("Lost previous note: not written"));

#ifdef DEBUG
          if (pn->next == nn)
            printf("* pn->next==nn\n");
#endif

          nn->next = pn->next;

#ifdef DEBUG
          if (pn2 == nn)
            printf("* pn2==nn\n");
#endif

          if (pn == *notetop)
            *notetop = nn;
          else
            pn2->next = nn;
          freenote(pn);
          pn = nn;

#ifdef DEBUG
          if (nn->next == nn)
            printf("* Circular list created\n");
#endif

        }

#ifdef DEBUG
        printf(" nn linked into note list\n");
        printf(" curtime=%lu/%lu\n", curtime->num, curtime->denom);
        printf(" nn->dur=%lu/%lu\n", nn->dur.num, nn->dur.denom);
#endif

        *ln = nn;
        ratass(lastnote, curtime);
        ratmul(&rattmp, &nn->lastdur, grpmul);
        ratadd(curtime, curtime, &rattmp);

#ifdef DEBUG
        printf(" curtime=%lu/%lu\n", curtime->num, curtime->denom);
        printf(" Done with note\n");
#endif

      }
    }
    scotungetc();
}
Ejemplo n.º 5
0
int main (int argc, char *argv[]) {

short int c;
short int readopt=0;
short int writeopt=0;
short int clearallopt=0;
short int onlynote=0;
int option_index = 0; /* getopt_long ci mette l'indice delle opzioni */
char arguments[4096];
/* For write */
int hour=0;
int minutes=0;
int day=0;
int month=0;
char note[4096];

while (1) {

static struct option long_options[] =
             {
               {"write", no_argument, 0, 'w'},
               {"day", required_argument, 0, 0},
               {"month", required_argument, 0, 0},
               {"hour", required_argument, 0, 0},
               {"minutes", required_argument, 0, 0},
               {"note", required_argument, 0, 0},
							 {"read", no_argument, 0, 'r'},
							 {"clear", no_argument, 0, 'c'},
               {"help", no_argument, 0, 'h'},
               {0, 0, 0, 0}
             };

	c=getopt_long(argc, argv, "wrch", long_options, &option_index);
	
	if (c==-1) break;

		switch (c) {
			case 'w':
				writeopt=1;
				break;
			case 'r':
				readopt=1;
				break; 	
			case 'c':
				clearallopt=1;
				break;
			case 'h':
				usage();
				return(-1);
			case 0:
				if( strcmp( "day", long_options[option_index].name ) == 0 ) {
        	day=atoi(optarg);
        }
				else if( strcmp( "month", long_options[option_index].name ) == 0 ) {
					month=atoi(optarg);
        }
				else if( strcmp( "hour", long_options[option_index].name ) == 0 ) {
					hour=atoi(optarg);
        }
				else if( strcmp( "minutes", long_options[option_index].name ) == 0 ) {
					minutes=atoi(optarg);
        }
				else if( strcmp( "note", long_options[option_index].name ) == 0 ) {
        	strcpy(note,optarg);
        }
			break;
			case '?': 
				usage();
				return(-1);	
			default:
				usage();
				return(-1);
		}
}

	/* 1 opzione alla volta */
	if ((writeopt&&readopt)||(writeopt&&clearallopt)||(clearallopt&&readopt)){
		usage();
		return -1;
	}

	if (readopt) {
		readnotes();
	}

	else if (clearallopt) {
		clearallnotes();
	}

	else if (writeopt) {
		if ((day+month+hour+minutes)==0)
			onlynote=1;
		//printf ("hour %d,minutes %d,day %d,month %d,note %s",hour,minutes,day,month,note);return 0;
		writenote (onlynote,hour,minutes,day,month,note);
		readnotes();
	}

	return (0);
}
Ejemplo n.º 6
0
int elfcore(int fd, FILE *fp, const char *path, long coresize)
{
procfs_sysinfo		*sysinfo;
int					sysinfo_len;
procfs_info			info;
procfs_status		status;
int					ret;
procfs_mapinfo		*mem = NULL, *mapinfos = NULL, *ldd_infos = NULL;
int					numnote=0, num, i, j, seg = 0, err, n_ldd_infos = 0;
Elf32_Ehdr			elf;
Elf32_Phdr 			phdr;
struct memelfnote	notes[20], thread_note;
off_t				offset = 0, dataoff;
uint64_t			cur_tid_base = 0, cur_tid_size = 0;


	if (nodumpmem) {
		if (-1 == get_ldd_mapinfos(fd, &ldd_infos, &n_ldd_infos)) {
			/* should we bail out here? */
			n_ldd_infos = 0;
		}
	}

	if((ret = devctl(fd, DCMD_PROC_SYSINFO, 0, 0, &sysinfo_len)) != EOK) {
		errno = ret;
		goto bailout;
	}
	if(sysinfo = alloca(sysinfo_len)) {
		if((ret = devctl(fd, DCMD_PROC_SYSINFO, sysinfo, sysinfo_len, 0)) != EOK) {
			errno = ret;
			goto bailout;
		}
	}

	if((ret = devctl(fd, DCMD_PROC_INFO, &info, sizeof info, 0)) != EOK) {
		errno = ret;
		goto bailout;
	}

	pagesize = sysconf( _SC_PAGESIZE );
	if ( membuf == NULL && ((membuf = malloc( pagesize )) == NULL) ) {
		goto bailout;
	}

	// write elf header
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELFCLASS32;
	elf.e_ident[EI_DATA] = ELFDATANATIVE;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
#if defined (__ARM__)
	elf.e_ident[EI_OSABI] = ELFOSABI_ARM;
#endif
	
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	if((ret = devctl(fd, DCMD_PROC_PAGEDATA, NULL, 0, &num)) != EOK) {
		errno = ret;
		goto bailout;
	}

	mapinfos = malloc( num * sizeof *mem );
	if ( mapinfos == NULL ) {
		goto bailout;
	}

	if((ret = devctl(fd, DCMD_PROC_PAGEDATA, mapinfos, num*sizeof(*mapinfos), &num)) != EOK) {
		errno = ret;
		goto bailout;
	}

	mem = malloc( (n_ldd_infos + num) * sizeof(*mem) );
	if ( mem == NULL ) {
		goto bailout;
	}

	/* find the offending thread */
	for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
		dprintf(("thread %d.flags is %#x\n", status.tid, status.flags ));
		if(status.why == _DEBUG_WHY_SIGNALLED) {
			// This is the faulting thread...
			dprintf(("thread %d is was SIGNALLED\n", status.tid ));
			cur_tid = status.tid;
			cur_tid_base = status.stkbase;
			cur_tid_size = status.stksize;
		}
		dprintf(("thread %d.why is %#x\n", status.tid, status.why ));
	}

	if(cur_tid == 0) {
		/* can't find the faulting thread then we need to dump all stack information */
		cur_tid_only = 0;
	}

	for(seg = 0, i = 0; i < num; i++) {
	  	if(!(mapinfos[i].flags & PG_HWMAPPED) ||
			(nodumpmem && !(mapinfos[i].flags & MAP_STACK)) ) {
			continue;
		}
		if ( (nodumpphys && (mapinfos[i].flags & MAP_PHYS) && !(mapinfos[i].flags & MAP_ANON)) ) {
			continue;
		}

		/* if we only want to dump the offending tid's stack */
		if(cur_tid_only && (mapinfos[i].flags & MAP_STACK) && 
			!OFFENDING_THREAD(cur_tid_base, cur_tid_size, &mapinfos[i])) {
			continue;
		}

		memcpy(&mem[seg], &mapinfos[i], sizeof(*mem));
		seg++;
	}

	dprintf(("ldd mapinfos:\n"));
	for(i = 0; i < n_ldd_infos; i++) {
		dprintf(("%svaddr=%#llx, offset=%#llx, size=%#llx, flags=%#x\n", ldd_infos[i].flags & PG_HWMAPPED?"*":"", ldd_infos[i].vaddr, ldd_infos[i].offset, ldd_infos[i].size, ldd_infos[i].flags ));
		memcpy( &mem[seg], &ldd_infos[i], sizeof(*mem));;
		seg++;
	}
	free(mapinfos);
	mapinfos = NULL;
	if(n_ldd_infos) {
		free(ldd_infos);
		ldd_infos = NULL;
	}
	num = seg;

	elf.e_type = ET_CORE;
	elf.e_machine = EM_NATIVE;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
#ifdef __SH__
	{
		struct cpuinfo_entry	*cpu;

		cpu = SYSPAGE_ENTRY(cpuinfo);
		switch ( SH4_PVR_FAM(cpu[0].cpu) ) {
			case SH4_PVR_SH4A:
				dprintf(("Noting SH4-A CPU\n"));
				elf.e_flags = EF_SH4A;
				break;
			case SH4_PVR_SH4:
			default:
				elf.e_flags = EF_SH4;
				break;
		}
	}
#else
	elf.e_flags = 0;
#endif
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(phdr);
	elf.e_phnum = seg+1; /* xxxx */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	if(dump_write( fp, &elf, sizeof elf, &coresize ) == -1)
		goto bailout;
	
	offset += sizeof elf;
	offset += (elf.e_phnum) * sizeof phdr;

	if(sysinfo) {
		// write QNT_CORE_SYSINFO note
		memset( notes, 0, sizeof notes );
		notes[numnote].name = QNX_NOTE_NAME;
		notes[numnote].type = QNT_CORE_SYSINFO;
		notes[numnote].datasz = roundup(sysinfo_len, sizeof (Elf32_Word));
		notes[numnote].data = sysinfo;
		numnote++;
	}

	// write QNT_CORE_INFO note
	notes[numnote].name = QNX_NOTE_NAME;
	notes[numnote].type = QNT_CORE_INFO;
	notes[numnote].datasz = sizeof(info);
	notes[numnote].data = &info;
	numnote++;

	/* Write notes phdr entry */
	{
		int sz = 0;

		memset( &phdr, 0, sizeof phdr );

		for(i = 0; i < numnote; i++)
		    sz += notesize(&notes[i]);

		for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
			procfs_greg					greg;
			procfs_fpreg				fpreg;
			int							size;

			if ( (err = devctl(fd, DCMD_PROC_CURTHREAD, &status.tid, sizeof status.tid, 0 )) != EOK ) {
				continue;
			}

			if (cur_tid_only && (cur_tid != status.tid)) {
				continue;
			}

			fixup_stack_boundary( &status, mem, seg );

			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_STATUS;
			thread_note.datasz = sizeof(status);
			thread_note.data = &status;
			sz += notesize( &thread_note );

			if(devctl(fd, DCMD_PROC_GETGREG, &greg, sizeof greg, &size) == EOK) {
				thread_note.name = QNX_NOTE_NAME;
				thread_note.type = QNT_CORE_GREG;
				thread_note.datasz = size;
				thread_note.data = &greg;
				sz += notesize( &thread_note );
			}
			if(devctl(fd, DCMD_PROC_GETFPREG, &fpreg, sizeof fpreg, &size) == EOK) {
				thread_note.name = QNX_NOTE_NAME;
				thread_note.type = QNT_CORE_FPREG;
				thread_note.datasz = size;
				thread_note.data = &fpreg;
				sz += notesize( &thread_note );
			}
		}

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		if(dump_write( fp, &phdr, sizeof(phdr), &coresize) == -1)
			goto bailout;
	}

	/* Page-align dumped data */
	dataoff = offset = roundup(offset, pagesize);

	for ( i = 0; i < seg; i++ ) {
		memset( &phdr, 0, sizeof phdr );

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = mem[i].vaddr;
		phdr.p_paddr = 0;
		phdr.p_memsz = mem[i].size;
		phdr.p_flags = PF_W|PF_R;
		if ( mem[i].flags & MAP_ELF )
			phdr.p_flags |= PF_X;
		phdr.p_align = pagesize;
		phdr.p_filesz = phdr.p_memsz;

		offset += phdr.p_filesz;
		if(dump_write( fp, &phdr, sizeof(phdr), &coresize) == -1)
			goto bailout;
	}

	for(i = 0; i < numnote; i++) {
	    if (!writenote(&notes[i], fp, &coresize ))
	    	goto bailout;
	}

	for(status.tid = 1; devctl(fd, DCMD_PROC_TIDSTATUS, &status, sizeof status, 0) == EOK; status.tid++) {
		procfs_greg					greg;
		procfs_fpreg				fpreg;
		int							size;

		if ( devctl(fd, DCMD_PROC_CURTHREAD, &status.tid, sizeof status.tid, 0 ) != EOK ) {
			continue;
		}

		if ( cur_tid == 0 )
			cur_tid = status.tid;

		if (cur_tid_only && (cur_tid != status.tid)) {
			continue;
		} else if ( status.tid == cur_tid ) {
			dprintf(("thread %d is current thread!\n", status.tid ));
			slog_tid( &status, path );
			status.flags |= _DEBUG_FLAG_CURTID;
		}

		// write QNT_CORE_STATUS note
		thread_note.name = QNX_NOTE_NAME;
		thread_note.type = QNT_CORE_STATUS;
		thread_note.datasz = sizeof(status);
		thread_note.data = &status;
		if ( !writenote( &thread_note, fp, &coresize ) )
			goto bailout;

		if(devctl(fd, DCMD_PROC_GETGREG, &greg, sizeof greg, &size) == EOK) {
			// write QNT_CORE_GREG note
			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_GREG;
			thread_note.datasz = size;
			thread_note.data = &greg;
			if ( !writenote( &thread_note, fp, &coresize ) )
				goto bailout;
		}

		if(devctl(fd, DCMD_PROC_GETFPREG, &fpreg, sizeof fpreg, &size) == EOK) {
			// write QNT_CORE_FPREG note
			thread_note.name = QNX_NOTE_NAME;
			thread_note.type = QNT_CORE_FPREG;
			thread_note.datasz = size;
			thread_note.data = &fpreg;
			if ( !writenote( &thread_note, fp, &coresize ) )
				goto bailout;
		}
	}

	dump_seek( fp, dataoff );

	for ( j = 0; j < seg; j++ ) {
		if ( lseek( fd, mem[j].vaddr, SEEK_SET ) == -1 )
			goto bailout;
		if ( mem[j].flags & MAP_STACK )
			dump_stack_memory( fd, fp, &mem[j], &coresize );
		else
		  if (!nodumpmem)
			dump_memory( fd, fp, &mem[j], &coresize );
	}

	// Return EOK when accually writing ELF files
	free(mem);
	return EOK;
bailout:
	if ( mapinfos != NULL ) {
		free(mapinfos);
	}
	if ( ldd_infos != NULL ) {
		free(ldd_infos);
	}
	if ( mem != NULL ) {
		free(mem);
	}
	return errno;
}
Ejemplo n.º 7
0
/*
 * Actual dumper
 *
 * This is a two-pass process; first we find the offsets of the bits,
 * and then they are actually written out.  If we run out of core limit
 * we just truncate.
 */
static int elf_core_dump(long signr, struct pt_regs * regs)
{
	int has_dumped = 0;
	struct file file;
	struct dentry *dentry;
	struct inode *inode;
	mm_segment_t fs;
	char corefile[6+sizeof(current->comm)];
	int segs;
	int i;
	size_t size;
	struct vm_area_struct *vma;
	struct elfhdr elf;
	off_t offset = 0, dataoff;
	unsigned long limit = current->rlim[RLIMIT_CORE].rlim_cur;
	int numnote = 4;
	struct memelfnote notes[4];
	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
	elf_fpregset_t fpu;		/* NT_PRFPREG */
	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */

	if (!current->dumpable ||
	    limit < ELF_EXEC_PAGESIZE ||
	    atomic_read(&current->mm->count) != 1)
		return 0;
	current->dumpable = 0;

#ifndef CONFIG_BINFMT_ELF
	MOD_INC_USE_COUNT;
#endif

	/* Count what's needed to dump, up to the limit of coredump size */
	segs = 0;
	size = 0;
	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
		if (maydump(vma))
		{
			unsigned long sz = vma->vm_end-vma->vm_start;

			if (size+sz >= limit)
				break;
			else
				size += sz;
		}

		segs++;
	}
#ifdef DEBUG
	printk("elf_core_dump: %d segs taking %d bytes\n", segs, size);
#endif

	/* Set up header */
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELF_CLASS;
	elf.e_ident[EI_DATA] = ELF_DATA;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	elf.e_type = ET_CORE;
	elf.e_machine = ELF_ARCH;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
	elf.e_flags = 0;
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(struct elf_phdr);
	elf.e_phnum = segs+1;		/* Include notes */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	fs = get_fs();
	set_fs(KERNEL_DS);
	memcpy(corefile,"core.",5);
#if 0
	memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
	corefile[4] = '\0';
#endif
	dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC | O_NOFOLLOW, 0600);
	if (IS_ERR(dentry)) {
		dentry = NULL;
		goto end_coredump;
	}
	inode = dentry->d_inode;

	if(inode->i_nlink > 1)
		goto end_coredump;	/* multiple links - don't dump */

	if (!S_ISREG(inode->i_mode))
		goto end_coredump;
	if (!inode->i_op || !inode->i_op->default_file_ops)
		goto end_coredump;
	if (init_private_file(&file, dentry, 3))
		goto end_coredump;
	if (!file.f_op->write)
		goto close_coredump;
	has_dumped = 1;
	current->flags |= PF_DUMPCORE;

	DUMP_WRITE(&elf, sizeof(elf));
	offset += sizeof(elf);				/* Elf header */
	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers */

	/*
	 * Set up the notes in similar form to SVR4 core dumps made
	 * with info from their /proc.
	 */
	memset(&psinfo, 0, sizeof(psinfo));
	memset(&prstatus, 0, sizeof(prstatus));

	notes[0].name = "CORE";
	notes[0].type = NT_PRSTATUS;
	notes[0].datasz = sizeof(prstatus);
	notes[0].data = &prstatus;
	prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
	prstatus.pr_sigpend = current->signal.sig[0];
	prstatus.pr_sighold = current->blocked.sig[0];
	psinfo.pr_pid = prstatus.pr_pid = current->pid;
	psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
	psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
	psinfo.pr_sid = prstatus.pr_sid = current->session;
	prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
	prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
	prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
	prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
	prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
	prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
	prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
	prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);

	/*
	 * This transfers the registers from regs into the standard
	 * coredump arrangement, whatever that is.
	 */
#ifdef ELF_CORE_COPY_REGS
	ELF_CORE_COPY_REGS(prstatus.pr_reg, regs)
#else
	if (sizeof(elf_gregset_t) != sizeof(struct pt_regs))
	{
		printk("sizeof(elf_gregset_t) (%ld) != sizeof(struct pt_regs) (%ld)\n",
			(long)sizeof(elf_gregset_t), (long)sizeof(struct pt_regs));
	}
	else
		*(struct pt_regs *)&prstatus.pr_reg = *regs;
#endif

#ifdef DEBUG
	dump_regs("Passed in regs", (elf_greg_t *)regs);
	dump_regs("prstatus regs", (elf_greg_t *)&prstatus.pr_reg);
#endif

	notes[1].name = "CORE";
	notes[1].type = NT_PRPSINFO;
	notes[1].datasz = sizeof(psinfo);
	notes[1].data = &psinfo;
	i = current->state ? ffz(~current->state) + 1 : 0;
	psinfo.pr_state = i;
	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
	psinfo.pr_nice = current->priority-15;
	psinfo.pr_flag = current->flags;
	psinfo.pr_uid = current->uid;
	psinfo.pr_gid = current->gid;
	{
		int i, len;

		set_fs(fs);

		len = current->mm->arg_end - current->mm->arg_start;
		if (len >= ELF_PRARGSZ)
			len = ELF_PRARGSZ-1;
		copy_from_user(&psinfo.pr_psargs,
			      (const char *)current->mm->arg_start, len);
		for(i = 0; i < len; i++)
			if (psinfo.pr_psargs[i] == 0)
				psinfo.pr_psargs[i] = ' ';
		psinfo.pr_psargs[len] = 0;

		set_fs(KERNEL_DS);
	}
	strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));

	notes[2].name = "CORE";
	notes[2].type = NT_TASKSTRUCT;
	notes[2].datasz = sizeof(*current);
	notes[2].data = current;

	/* Try to dump the FPU. */
	prstatus.pr_fpvalid = dump_fpu (regs, &fpu);
	if (!prstatus.pr_fpvalid)
	{
		numnote--;
	}
	else
	{
		notes[3].name = "CORE";
		notes[3].type = NT_PRFPREG;
		notes[3].datasz = sizeof(fpu);
		notes[3].data = &fpu;
	}
	
	/* Write notes phdr entry */
	{
		struct elf_phdr phdr;
		int sz = 0;

		for(i = 0; i < numnote; i++)
			sz += notesize(&notes[i]);

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	/* Page-align dumped data */
	dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);

	/* Write program headers for segments dump */
	for(vma = current->mm->mmap, i = 0;
		i < segs && vma != NULL; vma = vma->vm_next) {
		struct elf_phdr phdr;
		size_t sz;

		i++;

		sz = vma->vm_end - vma->vm_start;

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = vma->vm_start;
		phdr.p_paddr = 0;
		phdr.p_filesz = maydump(vma) ? sz : 0;
		phdr.p_memsz = sz;
		offset += phdr.p_filesz;
		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
		if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
		if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
		phdr.p_align = ELF_EXEC_PAGESIZE;

		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	for(i = 0; i < numnote; i++)
		if (!writenote(&notes[i], &file))
			goto close_coredump;

	set_fs(fs);

	DUMP_SEEK(dataoff);

	for(i = 0, vma = current->mm->mmap;
	    i < segs && vma != NULL;
	    vma = vma->vm_next) {
		unsigned long addr = vma->vm_start;
		unsigned long len = vma->vm_end - vma->vm_start;

		i++;
		if (!maydump(vma))
			continue;
#ifdef DEBUG
		printk("elf_core_dump: writing %08lx %lx\n", addr, len);
#endif
		DUMP_WRITE((void *)addr, len);
	}

	if ((off_t) file.f_pos != offset) {
		/* Sanity check */
		printk("elf_core_dump: file.f_pos (%ld) != offset (%ld)\n",
		       (off_t) file.f_pos, offset);
	}

 close_coredump:
	if (file.f_op->release)
		file.f_op->release(inode,&file);

 end_coredump:
	set_fs(fs);
	dput(dentry);
#ifndef CONFIG_BINFMT_ELF
	MOD_DEC_USE_COUNT;
#endif
	return has_dumped;
}
Ejemplo n.º 8
0
/* Actual dumper.
 *
 * This is a two-pass process; first we find the offsets of the bits,
 * and then they are actually written out.  If we run out of core limit
 * we just truncate.
 */
static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
{
	int has_dumped = 0;
	mm_segment_t fs;
	int segs;
	int i;
	size_t size;
	struct vm_area_struct *vma;
	struct elfhdr elf;
	off_t offset = 0, dataoff;
	int limit = current->rlim[RLIMIT_CORE].rlim_cur;
	int numnote = 4;
	struct memelfnote notes[4];
	struct elf_prstatus prstatus;	/* NT_PRSTATUS */
	elf_fpregset_t fpu;		/* NT_PRFPREG */
	struct elf_prpsinfo psinfo;	/* NT_PRPSINFO */

	/* Count what's needed to dump, up to the limit of coredump size. */
	segs = 0;
	size = 0;
	for(vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
		if (maydump(vma))
		{
			int sz = vma->vm_end-vma->vm_start;

			if (size+sz >= limit)
				break;
			else
				size += sz;
		}

		segs++;
	}
#ifdef DEBUG
	printk("irix_core_dump: %d segs taking %d bytes\n", segs, size);
#endif

	/* Set up header. */
	memcpy(elf.e_ident, ELFMAG, SELFMAG);
	elf.e_ident[EI_CLASS] = ELFCLASS32;
	elf.e_ident[EI_DATA] = ELFDATA2LSB;
	elf.e_ident[EI_VERSION] = EV_CURRENT;
	memset(elf.e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);

	elf.e_type = ET_CORE;
	elf.e_machine = ELF_ARCH;
	elf.e_version = EV_CURRENT;
	elf.e_entry = 0;
	elf.e_phoff = sizeof(elf);
	elf.e_shoff = 0;
	elf.e_flags = 0;
	elf.e_ehsize = sizeof(elf);
	elf.e_phentsize = sizeof(struct elf_phdr);
	elf.e_phnum = segs+1;		/* Include notes. */
	elf.e_shentsize = 0;
	elf.e_shnum = 0;
	elf.e_shstrndx = 0;

	fs = get_fs();
	set_fs(KERNEL_DS);

	has_dumped = 1;
	current->flags |= PF_DUMPCORE;

	DUMP_WRITE(&elf, sizeof(elf));
	offset += sizeof(elf);				/* Elf header. */
	offset += (segs+1) * sizeof(struct elf_phdr);	/* Program headers. */

	/* Set up the notes in similar form to SVR4 core dumps made
	 * with info from their /proc.
	 */
	memset(&psinfo, 0, sizeof(psinfo));
	memset(&prstatus, 0, sizeof(prstatus));

	notes[0].name = "CORE";
	notes[0].type = NT_PRSTATUS;
	notes[0].datasz = sizeof(prstatus);
	notes[0].data = &prstatus;
	prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
	prstatus.pr_sigpend = current->pending.signal.sig[0];
	prstatus.pr_sighold = current->blocked.sig[0];
	psinfo.pr_pid = prstatus.pr_pid = current->pid;
	psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
	psinfo.pr_pgrp = prstatus.pr_pgrp = current->pgrp;
	psinfo.pr_sid = prstatus.pr_sid = current->session;
	prstatus.pr_utime.tv_sec = CT_TO_SECS(current->times.tms_utime);
	prstatus.pr_utime.tv_usec = CT_TO_USECS(current->times.tms_utime);
	prstatus.pr_stime.tv_sec = CT_TO_SECS(current->times.tms_stime);
	prstatus.pr_stime.tv_usec = CT_TO_USECS(current->times.tms_stime);
	prstatus.pr_cutime.tv_sec = CT_TO_SECS(current->times.tms_cutime);
	prstatus.pr_cutime.tv_usec = CT_TO_USECS(current->times.tms_cutime);
	prstatus.pr_cstime.tv_sec = CT_TO_SECS(current->times.tms_cstime);
	prstatus.pr_cstime.tv_usec = CT_TO_USECS(current->times.tms_cstime);
	if (sizeof(elf_gregset_t) != sizeof(struct pt_regs)) {
		printk("sizeof(elf_gregset_t) (%d) != sizeof(struct pt_regs) "
		       "(%d)\n", sizeof(elf_gregset_t), sizeof(struct pt_regs));
	} else {
		*(struct pt_regs *)&prstatus.pr_reg = *regs;
	}

	notes[1].name = "CORE";
	notes[1].type = NT_PRPSINFO;
	notes[1].datasz = sizeof(psinfo);
	notes[1].data = &psinfo;
	i = current->state ? ffz(~current->state) + 1 : 0;
	psinfo.pr_state = i;
	psinfo.pr_sname = (i < 0 || i > 5) ? '.' : "RSDZTD"[i];
	psinfo.pr_zomb = psinfo.pr_sname == 'Z';
	psinfo.pr_nice = current->nice;
	psinfo.pr_flag = current->flags;
	psinfo.pr_uid = current->uid;
	psinfo.pr_gid = current->gid;
	{
		int i, len;

		set_fs(fs);

		len = current->mm->arg_end - current->mm->arg_start;
		len = len >= ELF_PRARGSZ ? ELF_PRARGSZ : len;
		copy_from_user(&psinfo.pr_psargs,
			       (const char *)current->mm->arg_start, len);
		for(i = 0; i < len; i++)
			if (psinfo.pr_psargs[i] == 0)
				psinfo.pr_psargs[i] = ' ';
		psinfo.pr_psargs[len] = 0;

		set_fs(KERNEL_DS);
	}
	strncpy(psinfo.pr_fname, current->comm, sizeof(psinfo.pr_fname));

	notes[2].name = "CORE";
	notes[2].type = NT_TASKSTRUCT;
	notes[2].datasz = sizeof(*current);
	notes[2].data = current;

	/* Try to dump the FPU. */
	prstatus.pr_fpvalid = dump_fpu (&fpu);
	if (!prstatus.pr_fpvalid) {
		numnote--;
	} else {
		notes[3].name = "CORE";
		notes[3].type = NT_PRFPREG;
		notes[3].datasz = sizeof(fpu);
		notes[3].data = &fpu;
	}

	/* Write notes phdr entry. */
	{
		struct elf_phdr phdr;
		int sz = 0;

		for(i = 0; i < numnote; i++)
			sz += notesize(&notes[i]);

		phdr.p_type = PT_NOTE;
		phdr.p_offset = offset;
		phdr.p_vaddr = 0;
		phdr.p_paddr = 0;
		phdr.p_filesz = sz;
		phdr.p_memsz = 0;
		phdr.p_flags = 0;
		phdr.p_align = 0;

		offset += phdr.p_filesz;
		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	/* Page-align dumped data. */
	dataoff = offset = roundup(offset, PAGE_SIZE);

	/* Write program headers for segments dump. */
	for(vma = current->mm->mmap, i = 0;
		i < segs && vma != NULL; vma = vma->vm_next) {
		struct elf_phdr phdr;
		size_t sz;

		i++;

		sz = vma->vm_end - vma->vm_start;

		phdr.p_type = PT_LOAD;
		phdr.p_offset = offset;
		phdr.p_vaddr = vma->vm_start;
		phdr.p_paddr = 0;
		phdr.p_filesz = maydump(vma) ? sz : 0;
		phdr.p_memsz = sz;
		offset += phdr.p_filesz;
		phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
		if (vma->vm_flags & VM_WRITE) phdr.p_flags |= PF_W;
		if (vma->vm_flags & VM_EXEC) phdr.p_flags |= PF_X;
		phdr.p_align = PAGE_SIZE;

		DUMP_WRITE(&phdr, sizeof(phdr));
	}

	for(i = 0; i < numnote; i++)
		if (!writenote(&notes[i], file))
			goto end_coredump;

	set_fs(fs);

	DUMP_SEEK(dataoff);

	for(i = 0, vma = current->mm->mmap;
	    i < segs && vma != NULL;
	    vma = vma->vm_next) {
		unsigned long addr = vma->vm_start;
		unsigned long len = vma->vm_end - vma->vm_start;

		if (!maydump(vma))
			continue;
		i++;
#ifdef DEBUG
		printk("elf_core_dump: writing %08lx %lx\n", addr, len);
#endif
		DUMP_WRITE((void *)addr, len);
	}

	if ((off_t) file->f_pos != offset) {
		/* Sanity check. */
		printk("elf_core_dump: file->f_pos (%ld) != offset (%ld)\n",
		       (off_t) file->f_pos, offset);
	}

end_coredump:
	set_fs(fs);
	return has_dumped;
}