summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/imgact_elf.c10
-rw-r--r--sys/kern/kern_fork.c2
-rw-r--r--sys/sys/proc.h8
-rw-r--r--usr.bin/gcore/elfcore.c23
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;
OpenPOWER on IntegriCloud