diff options
-rw-r--r-- | sys/kern/imgact_elf.c | 10 | ||||
-rw-r--r-- | sys/kern/kern_fork.c | 2 | ||||
-rw-r--r-- | sys/sys/proc.h | 8 | ||||
-rw-r--r-- | usr.bin/gcore/elfcore.c | 23 |
4 files changed, 27 insertions, 16 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 491b9dd..6ae6d67 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -1079,6 +1079,8 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->interpreted = 0; imgp->reloc_base = addr; imgp->proc->p_osrel = osrel; + imgp->proc->p_elf_machine = hdr->e_machine; + imgp->proc->p_elf_flags = hdr->e_flags; ret: free(interp_buf, M_TEMP); @@ -1682,15 +1684,11 @@ __elfN(puthdr)(struct thread *td, void *hdr, size_t hdrsize, int numsegs, ehdr->e_ident[EI_ABIVERSION] = 0; ehdr->e_ident[EI_PAD] = 0; ehdr->e_type = ET_CORE; -#if defined(COMPAT_FREEBSD32) && __ELF_WORD_SIZE == 32 - ehdr->e_machine = ELF_ARCH32; -#else - ehdr->e_machine = ELF_ARCH; -#endif + ehdr->e_machine = td->td_proc->p_elf_machine; ehdr->e_version = EV_CURRENT; ehdr->e_entry = 0; ehdr->e_phoff = sizeof(Elf_Ehdr); - ehdr->e_flags = 0; + ehdr->e_flags = td->td_proc->p_elf_flags; ehdr->e_ehsize = sizeof(Elf_Ehdr); ehdr->e_phentsize = sizeof(Elf_Phdr); ehdr->e_phnum = numsegs + 1; diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index bb92861..c7680aa 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -408,6 +408,8 @@ do_fork(struct thread *td, struct fork_req *fr, struct proc *p2, struct thread * bcopy(&p1->p_startcopy, &p2->p_startcopy, __rangeof(struct proc, p_startcopy, p_endcopy)); + p2->p_elf_machine = p1->p_elf_machine; + p2->p_elf_flags = p1->p_elf_flags; pargs_hold(p2->p_args); PROC_UNLOCK(p1); diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 2439e11..5946298 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -316,7 +316,7 @@ struct thread { } td_state; /* (t) thread state */ union { register_t tdu_retval[2]; - off_t tdu_off; + off_t tdu_off; } td_uretoff; /* (k) Syscall aux returns. */ #define td_retval td_uretoff.tdu_retval u_int td_cowgen; /* (k) Generation of COW pointers. */ @@ -626,8 +626,10 @@ struct proc { our subtree. */ u_int p_xexit; /* (c) Exit code. */ u_int p_xsig; /* (c) Stop/kill sig. */ + /* End area that is copied on creation. */ -#define p_endcopy p_xsig +#define p_endcopy p_pgrp + struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */ struct knlist *p_klist; /* (c) Knotes attached to this proc. */ int p_numthreads; /* (c) Number of threads. */ @@ -657,6 +659,8 @@ struct proc { LIST_ENTRY(proc) p_orphan; /* (e) List of orphan processes. */ LIST_HEAD(, proc) p_orphans; /* (e) Pointer to list of orphans. */ u_int p_ptevents; /* (c) ptrace() event mask. */ + uint16_t p_elf_machine; /* (x) ELF machine type */ + uint64_t p_elf_flags; /* (x) ELF flags */ }; #define p_session p_pgrp->pg_session diff --git a/usr.bin/gcore/elfcore.c b/usr.bin/gcore/elfcore.c index 6f617ee..0a09888 100644 --- a/usr.bin/gcore/elfcore.c +++ b/usr.bin/gcore/elfcore.c @@ -117,8 +117,8 @@ static void *elf_note_procstat_psstrings(void *, size_t *); static void *elf_note_procstat_rlimit(void *, size_t *); static void *elf_note_procstat_umask(void *, size_t *); static void *elf_note_procstat_vmmap(void *, size_t *); -static void elf_puthdr(pid_t, vm_map_entry_t, void *, size_t, size_t, size_t, - int); +static void elf_puthdr(int, pid_t, vm_map_entry_t, void *, size_t, size_t, + size_t, int); static void elf_putnote(int, notefunc_t, void *, struct sbuf *); static void elf_putnotes(pid_t, struct sbuf *, size_t *); static void freemap(vm_map_entry_t); @@ -178,7 +178,7 @@ elf_detach(void) * Write an ELF coredump for the given pid to the given fd. */ static void -elf_coredump(int efd __unused, int fd, pid_t pid) +elf_coredump(int efd, int fd, pid_t pid) { vm_map_entry_t map; struct sseg_closure seginfo; @@ -228,7 +228,7 @@ elf_coredump(int efd __unused, int fd, pid_t pid) hdr = sbuf_data(sb); segoff = sbuf_len(sb); /* Fill in the header. */ - elf_puthdr(pid, map, hdr, hdrsize, notesz, segoff, seginfo.count); + elf_puthdr(efd, pid, map, hdr, hdrsize, notesz, segoff, seginfo.count); n = write(fd, hdr, segoff); if (n == -1) @@ -418,12 +418,19 @@ elf_putnote(int type, notefunc_t notefunc, void *arg, struct sbuf *sb) * Generate the ELF coredump header. */ static void -elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize, +elf_puthdr(int efd, pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize, size_t notesz, size_t segoff, int numsegs) { - Elf_Ehdr *ehdr; + Elf_Ehdr *ehdr, binhdr; Elf_Phdr *phdr; struct phdr_closure phc; + ssize_t cnt; + + cnt = read(efd, &binhdr, sizeof(binhdr)); + if (cnt < 0) + err(1, "Failed to re-read ELF header"); + else if (cnt != sizeof(binhdr)) + errx(1, "Failed to re-read ELF header"); ehdr = (Elf_Ehdr *)hdr; phdr = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)); @@ -439,11 +446,11 @@ elf_puthdr(pid_t pid, vm_map_entry_t map, void *hdr, size_t hdrsize, ehdr->e_ident[EI_ABIVERSION] = 0; ehdr->e_ident[EI_PAD] = 0; ehdr->e_type = ET_CORE; - ehdr->e_machine = ELF_ARCH; + ehdr->e_machine = binhdr.e_machine; ehdr->e_version = EV_CURRENT; ehdr->e_entry = 0; ehdr->e_phoff = sizeof(Elf_Ehdr); - ehdr->e_flags = 0; + ehdr->e_flags = binhdr.e_flags; ehdr->e_ehsize = sizeof(Elf_Ehdr); ehdr->e_phentsize = sizeof(Elf_Phdr); ehdr->e_phnum = numsegs + 1; |