Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137142786
D30019.id90712.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
24 KB
Referenced Files
None
Subscribers
None
D30019.id90712.diff
View Options
Index: sys/amd64/linux/linux_sysvec.c
===================================================================
--- sys/amd64/linux/linux_sysvec.c
+++ sys/amd64/linux/linux_sysvec.c
@@ -739,7 +739,7 @@
.sv_sigcode = &_binary_linux_locore_o_start,
.sv_szsigcode = &linux_szsigcode,
.sv_name = "Linux ELF64",
- .sv_coredump = elf64_coredump,
+ .sv_coredump = linux64_coredump,
.sv_imgact_try = linux_exec_imgact_try,
.sv_minsigstksz = LINUX_MINSIGSTKSZ,
.sv_minuser = VM_MIN_ADDRESS,
Index: sys/amd64/linux32/linux32_sysvec.c
===================================================================
--- sys/amd64/linux32/linux32_sysvec.c
+++ sys/amd64/linux32/linux32_sysvec.c
@@ -906,7 +906,7 @@
.sv_sigcode = &_binary_linux32_locore_o_start,
.sv_szsigcode = &linux_szsigcode,
.sv_name = "Linux ELF32",
- .sv_coredump = elf32_coredump,
+ .sv_coredump = linux32_coredump,
.sv_imgact_try = linux_exec_imgact_try,
.sv_minsigstksz = LINUX_MINSIGSTKSZ,
.sv_minuser = VM_MIN_ADDRESS,
Index: sys/compat/linux/linux_elf.h
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_elf.h
@@ -0,0 +1,56 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Chuck Tuffli
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _COMPAT_LINUX_ELF_H_
+#define _COMPAT_LINUX_ELF_H_
+
+struct l_elf_siginfo {
+ l_int si_signo;
+ l_int si_code;
+ l_int si_errno;
+};
+
+typedef struct linux_pt_regset l_elf_gregset_t;
+
+struct linux_elf_prstatus {
+ struct l_elf_siginfo pr_info;
+ l_short pr_cursig;
+ l_ulong pr_sigpend;
+ l_ulong pr_sighold;
+ l_pid_t pr_pid;
+ l_pid_t pr_ppid;
+ l_pid_t pr_pgrp;
+ l_pid_t pr_sid;
+ l_timeval pr_utime;
+ l_timeval pr_stime;
+ l_timeval pr_cutime;
+ l_timeval pr_cstime;
+ l_elf_gregset_t pr_reg;
+ l_int pr_fpvalid;
+};
+
+#endif
Index: sys/compat/linux/linux_elf.c
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_elf.c
@@ -0,0 +1,529 @@
+/*-
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2021 Edward Tomasz Napierala <trasz@FreeBSD.org>
+ * Copyright (c) 2018 Chuck Tuffli
+ * Copyright (c) 2017 Dell EMC
+ * Copyright (c) 2000 David O'Brien
+ * Copyright (c) 1995-1996 Søren Schmidt
+ * Copyright (c) 1996 Peter Wemm
+ * All rights reserved.
+ *
+ * This software was developed by the University of Cambridge Computer
+ * Laboratory as part of the CHERI for Hypervisors and Operating Systems
+ * (CHaOS) project, funded by EPSRC grant EP/V000292/1.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer
+ * in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/procfs.h>
+#include <sys/ptrace.h>
+#include <sys/racct.h>
+#include <sys/sbuf.h>
+#include <sys/sysent.h>
+#include <sys/syslog.h>
+#include <sys/user.h>
+#include <sys/vnode.h>
+
+#include <machine/elf.h>
+
+#if defined(COMPAT_LINUX32) && __ELF_WORD_SIZE == 32
+#define linux_pt_regset linux_pt_regset32
+#define bsd_to_linux_regset bsd_to_linux_regset32
+#include <machine/../linux32/linux.h>
+#else
+#include <machine/../linux/linux.h>
+#endif
+#include <compat/linux/linux_elf.h>
+#include <compat/linux/linux_emul.h>
+#include <compat/linux/linux_misc.h>
+
+#define __linuxN(x) __CONCAT(__CONCAT(__CONCAT(linux,__ELF_WORD_SIZE),_),x)
+
+#define ELF_NOTE_ROUNDSIZE 4
+#define CORE_BUF_SIZE (16 * 1024)
+
+#define LINUX_NT_AUXV 6
+
+/* Linux core notes are labeled "CORE" */
+static const char LINUX_ABI_VENDOR[] = "CORE";
+
+/*
+ * Code for generating ELF core dumps.
+ */
+
+typedef void (*outfunc_t)(void *, struct sbuf *, size_t *);
+
+struct note_info {
+ int type; /* Note type. */
+ outfunc_t outfunc; /* Output function. */
+ void *outarg; /* Argument for the output function. */
+ size_t outsize; /* Output size. */
+ TAILQ_ENTRY(note_info) link; /* Link to the next note info. */
+};
+
+TAILQ_HEAD(note_info_list, note_info);
+
+static int corehdr(struct coredump_params *, int, void *, size_t,
+ struct note_info_list *, size_t, int);
+static void prepare_notes(struct thread *, struct note_info_list *,
+ size_t *);
+static void putnote(struct note_info *, struct sbuf *);
+static size_t register_note(struct note_info_list *, int, outfunc_t, void *);
+
+static void note_fpregset(void *, struct sbuf *, size_t *);
+static void note_prpsinfo(void *, struct sbuf *, size_t *);
+static void note_prstatus(void *, struct sbuf *, size_t *);
+static void note_threadmd(void *, struct sbuf *, size_t *);
+static void note_linux_nt_auxv(void *, struct sbuf *, size_t *);
+
+int
+__linuxN(coredump)(struct thread *td, struct vnode *vp, off_t limit, int flags)
+{
+ struct ucred *cred = td->td_ucred;
+ int error;
+ struct sseg_closure seginfo;
+ struct note_info_list notelst;
+ struct coredump_params params;
+ struct note_info *ninfo;
+ void *hdr;
+ size_t hdrsize, notesz, coresize;
+
+ hdr = NULL;
+ TAILQ_INIT(¬elst);
+
+ /* Size the program segments. */
+ __elfN(size_segments)(td, &seginfo, flags);
+
+ /*
+ * Collect info about the core file header area.
+ */
+ hdrsize = sizeof(Elf_Ehdr) + sizeof(Elf_Phdr) * (1 + seginfo.count);
+ if (seginfo.count + 1 >= PN_XNUM)
+ hdrsize += sizeof(Elf_Shdr);
+ prepare_notes(td, ¬elst, ¬esz);
+ coresize = round_page(hdrsize + notesz) + seginfo.size;
+
+ /* Set up core dump parameters. */
+ params.offset = 0;
+ params.active_cred = cred;
+ params.file_cred = NOCRED;
+ params.td = td;
+ params.vp = vp;
+ params.comp = NULL;
+
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(td->td_proc);
+ error = racct_add(td->td_proc, RACCT_CORE, coresize);
+ PROC_UNLOCK(td->td_proc);
+ if (error != 0) {
+ error = EFAULT;
+ goto done;
+ }
+ }
+#endif
+ if (coresize >= limit) {
+ error = EFAULT;
+ goto done;
+ }
+
+ /*
+ * Allocate memory for building the header, fill it up,
+ * and write it out following the notes.
+ */
+ hdr = malloc(hdrsize, M_TEMP, M_WAITOK);
+ error = corehdr(¶ms, seginfo.count, hdr, hdrsize, ¬elst,
+ notesz, flags);
+
+ /* Write the contents of all of the writable segments. */
+ if (error == 0) {
+ Elf_Phdr *php;
+ off_t offset;
+ int i;
+
+ php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1;
+ offset = round_page(hdrsize + notesz);
+ for (i = 0; i < seginfo.count; i++) {
+ error = core_output((caddr_t)(uintptr_t)php->p_vaddr,
+ php->p_filesz, offset, ¶ms, NULL);
+ if (error != 0)
+ break;
+ offset += php->p_filesz;
+ php++;
+ }
+ }
+ if (error) {
+ log(LOG_WARNING,
+ "Failed to write core file for process %s (error %d)\n",
+ curproc->p_comm, error);
+ }
+
+done:
+ while ((ninfo = TAILQ_FIRST(¬elst)) != NULL) {
+ TAILQ_REMOVE(¬elst, ninfo, link);
+ free(ninfo, M_TEMP);
+ }
+ if (hdr != NULL)
+ free(hdr, M_TEMP);
+
+ return (error);
+}
+
+/*
+ * Write the core file header to the file, including padding up to
+ * the page boundary.
+ */
+static int
+corehdr(struct coredump_params *p, int numsegs, void *hdr,
+ size_t hdrsize, struct note_info_list *notelst, size_t notesz, int flags)
+{
+ Elf_Ehdr *ehdr;
+ struct note_info *ninfo;
+ struct sbuf *sb;
+ int error;
+
+ /* Fill in the header. */
+ bzero(hdr, hdrsize);
+ ehdr = (Elf_Ehdr *)hdr;
+ ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE;
+ __elfN(puthdr)(p->td, hdr, hdrsize, numsegs, notesz, flags);
+
+ sb = sbuf_new(NULL, NULL, CORE_BUF_SIZE, SBUF_FIXEDLEN);
+ sbuf_set_drain(sb, sbuf_drain_core_output, p);
+ sbuf_start_section(sb, NULL);
+ sbuf_bcat(sb, hdr, hdrsize);
+ TAILQ_FOREACH(ninfo, notelst, link)
+ putnote(ninfo, sb);
+ /* Align up to a page boundary for the program segments. */
+ sbuf_end_section(sb, -1, PAGE_SIZE, 0);
+ error = sbuf_finish(sb);
+ sbuf_delete(sb);
+
+ return (error);
+}
+
+static void
+prepare_notes(struct thread *td, struct note_info_list *list,
+ size_t *sizep)
+{
+ struct proc *p;
+ struct thread *thr;
+ size_t size;
+
+ p = td->td_proc;
+ size = 0;
+
+ /*
+ * To have the debugger select the right thread (LWP) as the initial
+ * thread, we dump the state of the thread passed to us in td first.
+ * This is the thread that causes the core dump and thus likely to
+ * be the right thread one wants to have selected in the debugger.
+ */
+ thr = td;
+ while (thr != NULL) {
+ size += register_note(list, NT_PRSTATUS, note_prstatus, thr);
+ size += register_note(list, NT_PRPSINFO, note_prpsinfo, p);
+ size += register_note(list, LINUX_NT_AUXV, note_linux_nt_auxv, p);
+ size += register_note(list, NT_FPREGSET, note_fpregset, thr);
+ size += register_note(list, -1,
+ note_threadmd, thr);
+
+ thr = (thr == td) ? TAILQ_FIRST(&p->p_threads) :
+ TAILQ_NEXT(thr, td_plist);
+ if (thr == td)
+ thr = TAILQ_NEXT(thr, td_plist);
+ }
+
+ *sizep = size;
+}
+
+static size_t
+register_note(struct note_info_list *list, int type, outfunc_t out, void *arg)
+{
+ struct note_info *ninfo;
+ size_t size, notesize;
+
+ size = 0;
+ out(arg, NULL, &size);
+ ninfo = malloc(sizeof(*ninfo), M_TEMP, M_ZERO | M_WAITOK);
+ ninfo->type = type;
+ ninfo->outfunc = out;
+ ninfo->outarg = arg;
+ ninfo->outsize = size;
+ TAILQ_INSERT_TAIL(list, ninfo, link);
+
+ if (type == -1)
+ return (size);
+
+ notesize = sizeof(Elf_Note) + /* note header */
+ roundup2(sizeof(LINUX_ABI_VENDOR), ELF_NOTE_ROUNDSIZE) +
+ /* note name */
+ roundup2(size, ELF_NOTE_ROUNDSIZE); /* note description */
+
+ return (notesize);
+}
+
+static void
+putnote(struct note_info *ninfo, struct sbuf *sb)
+{
+ Elf_Note note;
+ ssize_t old_len, sect_len;
+ size_t new_len, descsz, i;
+
+ if (ninfo->type == -1) {
+ ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize);
+ return;
+ }
+
+ note.n_namesz = sizeof(LINUX_ABI_VENDOR);
+ note.n_descsz = ninfo->outsize;
+ note.n_type = ninfo->type;
+
+ sbuf_bcat(sb, ¬e, sizeof(note));
+ sbuf_start_section(sb, &old_len);
+ sbuf_bcat(sb, LINUX_ABI_VENDOR, sizeof(LINUX_ABI_VENDOR));
+ sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0);
+ if (note.n_descsz == 0)
+ return;
+ sbuf_start_section(sb, &old_len);
+ ninfo->outfunc(ninfo->outarg, sb, &ninfo->outsize);
+ sect_len = sbuf_end_section(sb, old_len, ELF_NOTE_ROUNDSIZE, 0);
+ if (sect_len < 0)
+ return;
+
+ new_len = (size_t)sect_len;
+ descsz = roundup(note.n_descsz, ELF_NOTE_ROUNDSIZE);
+ if (new_len < descsz) {
+ /*
+ * It is expected that individual note emitters will correctly
+ * predict their expected output size and fill up to that size
+ * themselves, padding in a format-specific way if needed.
+ * However, in case they don't, just do it here with zeros.
+ */
+ for (i = 0; i < descsz - new_len; i++)
+ sbuf_putc(sb, 0);
+ } else if (new_len > descsz) {
+ /*
+ * We can't always truncate sb -- we may have drained some
+ * of it already.
+ */
+ KASSERT(new_len == descsz, ("%s: Note type %u changed as we "
+ "read it (%zu > %zu). Since it is longer than "
+ "expected, this coredump's notes are corrupt. THIS "
+ "IS A BUG in the note_procstat routine for type %u.\n",
+ __func__, (unsigned)note.n_type, new_len, descsz,
+ (unsigned)note.n_type));
+ }
+}
+
+/*
+ * Miscellaneous note out functions.
+ */
+
+#if defined(COMPAT_LINUX32) && __ELF_WORD_SIZE == 32
+typedef struct linux_elf_prstatus elf_prstatus_t;
+typedef struct prpsinfo32 elf_prpsinfo_t;
+typedef struct fpreg32 elf_prfpregset_t;
+#else
+typedef struct linux_elf_prstatus elf_prstatus_t;
+typedef prpsinfo_t elf_prpsinfo_t;
+typedef prfpregset_t elf_prfpregset_t;
+#endif
+
+static void
+note_prpsinfo(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct sbuf sbarg;
+ size_t len;
+ char *cp, *end;
+ struct proc *p;
+ elf_prpsinfo_t *psinfo;
+ int error;
+
+ p = (struct proc *)arg;
+ if (sb != NULL) {
+ KASSERT(*sizep == sizeof(*psinfo), ("invalid size"));
+ psinfo = malloc(sizeof(*psinfo), M_TEMP, M_ZERO | M_WAITOK);
+ psinfo->pr_version = PRPSINFO_VERSION;
+ psinfo->pr_psinfosz = sizeof(elf_prpsinfo_t);
+ strlcpy(psinfo->pr_fname, p->p_comm, sizeof(psinfo->pr_fname));
+ PROC_LOCK(p);
+ if (p->p_args != NULL) {
+ len = sizeof(psinfo->pr_psargs) - 1;
+ if (len > p->p_args->ar_length)
+ len = p->p_args->ar_length;
+ memcpy(psinfo->pr_psargs, p->p_args->ar_args, len);
+ PROC_UNLOCK(p);
+ error = 0;
+ } else {
+ _PHOLD(p);
+ PROC_UNLOCK(p);
+ sbuf_new(&sbarg, psinfo->pr_psargs,
+ sizeof(psinfo->pr_psargs), SBUF_FIXEDLEN);
+ error = proc_getargv(curthread, p, &sbarg);
+ PRELE(p);
+ if (sbuf_finish(&sbarg) == 0)
+ len = sbuf_len(&sbarg) - 1;
+ else
+ len = sizeof(psinfo->pr_psargs) - 1;
+ sbuf_delete(&sbarg);
+ }
+ if (error || len == 0)
+ strlcpy(psinfo->pr_psargs, p->p_comm,
+ sizeof(psinfo->pr_psargs));
+ else {
+ KASSERT(len < sizeof(psinfo->pr_psargs),
+ ("len is too long: %zu vs %zu", len,
+ sizeof(psinfo->pr_psargs)));
+ cp = psinfo->pr_psargs;
+ end = cp + len - 1;
+ for (;;) {
+ cp = memchr(cp, '\0', end - cp);
+ if (cp == NULL)
+ break;
+ *cp = ' ';
+ }
+ }
+ psinfo->pr_pid = p->p_pid;
+ sbuf_bcat(sb, psinfo, sizeof(*psinfo));
+ free(psinfo, M_TEMP);
+ }
+ *sizep = sizeof(*psinfo);
+}
+
+static void
+note_prstatus(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct thread *td;
+ elf_prstatus_t *status;
+#if defined(COMPAT_LINUX32) && __ELF_WORD_SIZE == 32
+ struct reg32 pr_reg;
+#else
+ struct reg pr_reg;
+#endif
+
+ td = (struct thread *)arg;
+ if (sb != NULL) {
+ KASSERT(*sizep == sizeof(*status), ("invalid size"));
+ status = malloc(sizeof(*status), M_TEMP, M_ZERO | M_WAITOK);
+
+ /*
+ * XXX: Some fields missing.
+ */
+ status->pr_cursig = td->td_proc->p_sig;
+ status->pr_pid = td->td_tid;
+
+#if defined(COMPAT_LINUX32) && __ELF_WORD_SIZE == 32
+ fill_regs32(td, &pr_reg);
+#else
+ fill_regs(td, &pr_reg);
+#endif
+ bsd_to_linux_regset(&pr_reg, &status->pr_reg);
+ sbuf_bcat(sb, status, sizeof(*status));
+ free(status, M_TEMP);
+ }
+ *sizep = sizeof(*status);
+}
+
+static void
+note_fpregset(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct thread *td;
+ elf_prfpregset_t *fpregset;
+
+ td = (struct thread *)arg;
+ if (sb != NULL) {
+ KASSERT(*sizep == sizeof(*fpregset), ("invalid size"));
+ fpregset = malloc(sizeof(*fpregset), M_TEMP, M_ZERO | M_WAITOK);
+#if defined(COMPAT_LINUX32) && __ELF_WORD_SIZE == 32
+ fill_fpregs32(td, fpregset);
+#else
+ fill_fpregs(td, fpregset);
+#endif
+ sbuf_bcat(sb, fpregset, sizeof(*fpregset));
+ free(fpregset, M_TEMP);
+ }
+ *sizep = sizeof(*fpregset);
+}
+
+/*
+ * Allow for MD specific notes, as well as any MD
+ * specific preparations for writing MI notes.
+ */
+static void
+note_threadmd(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct thread *td;
+ void *buf;
+ size_t size;
+
+ td = (struct thread *)arg;
+ size = *sizep;
+ if (size != 0 && sb != NULL)
+ buf = malloc(size, M_TEMP, M_ZERO | M_WAITOK);
+ else
+ buf = NULL;
+ size = 0;
+ __elfN(dump_thread)(td, buf, &size);
+ KASSERT(sb == NULL || *sizep == size, ("invalid size"));
+ if (size != 0 && sb != NULL)
+ sbuf_bcat(sb, buf, size);
+ free(buf, M_TEMP);
+ *sizep = size;
+}
+
+static void
+note_linux_nt_auxv(void *arg, struct sbuf *sb, size_t *sizep)
+{
+ struct proc *p;
+ size_t size;
+
+ p = (struct proc *)arg;
+ if (sb == NULL) {
+ size = 0;
+ sb = sbuf_new(NULL, NULL, 320, SBUF_FIXEDLEN);
+ sbuf_set_drain(sb, sbuf_count_drain, &size);
+ PHOLD(p);
+ proc_getauxv(curthread, p, sb);
+ PRELE(p);
+ sbuf_finish(sb);
+ sbuf_delete(sb);
+ *sizep = size;
+ } else {
+ PHOLD(p);
+ proc_getauxv(curthread, p, sb);
+ PRELE(p);
+ }
+}
Index: sys/compat/linux/linux_elf32.c
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_elf32.c
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Edward Tomasz Napierala <trasz@FreeBSD.org>
+ * Copyright (c) 2002 Doug Rabson
+ * All rights reserved.
+ *
+ * This software was developed by the University of Cambridge Computer
+ * Laboratory as part of the CHERI for Hypervisors and Operating Systems
+ * (CHaOS) project, funded by EPSRC grant EP/V000292/1.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 32
+#include <compat/linux/linux_elf.c>
Index: sys/compat/linux/linux_elf64.c
===================================================================
--- /dev/null
+++ sys/compat/linux/linux_elf64.c
@@ -0,0 +1,38 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Edward Tomasz Napierala <trasz@FreeBSD.org>
+ * Copyright (c) 2002 Doug Rabson
+ * All rights reserved.
+ *
+ * This software was developed by the University of Cambridge Computer
+ * Laboratory as part of the CHERI for Hypervisors and Operating Systems
+ * (CHaOS) project, funded by EPSRC grant EP/V000292/1.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define __ELF_WORD_SIZE 64
+#include <compat/linux/linux_elf.c>
Index: sys/compat/linux/linux_emul.h
===================================================================
--- sys/compat/linux/linux_emul.h
+++ sys/compat/linux/linux_emul.h
@@ -58,6 +58,8 @@
void linux_thread_dtor(struct thread *);
void linux_thread_detach(struct thread *);
int linux_common_execve(struct thread *, struct image_args *);
+int linux32_coredump(struct thread *, struct vnode *, off_t, int);
+int linux64_coredump(struct thread *, struct vnode *, off_t, int);
/* process emuldata flags */
#define LINUX_XDEPR_REQUEUEOP 0x00000001 /* uses deprecated
Index: sys/kern/imgact_elf.c
===================================================================
--- sys/kern/imgact_elf.c
+++ sys/kern/imgact_elf.c
@@ -1722,12 +1722,15 @@
size_t hdrsize, struct note_info_list *notelst, size_t notesz,
int flags)
{
+ Elf_Ehdr *ehdr;
struct note_info *ninfo;
struct sbuf *sb;
int error;
/* Fill in the header. */
bzero(hdr, hdrsize);
+ ehdr = (Elf_Ehdr *)hdr;
+ ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
__elfN(puthdr)(p->td, hdr, hdrsize, numsegs, notesz, flags);
sb = sbuf_new(NULL, NULL, CORE_BUF_SIZE, SBUF_FIXEDLEN);
@@ -1822,7 +1825,7 @@
ehdr->e_ident[EI_CLASS] = ELF_CLASS;
ehdr->e_ident[EI_DATA] = ELF_DATA;
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
- ehdr->e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
+ /* e_ident[EI_OSABI] is to be already filled in by the caller. */
ehdr->e_ident[EI_ABIVERSION] = 0;
ehdr->e_ident[EI_PAD] = 0;
ehdr->e_type = ET_CORE;
Index: sys/modules/linux/Makefile
===================================================================
--- sys/modules/linux/Makefile
+++ sys/modules/linux/Makefile
@@ -13,7 +13,7 @@
VDSO= linux${SFX}_vdso
KMOD= linux
-SRCS= linux_fork.c linux${SFX}_dummy_machdep.c linux_file.c linux_event.c \
+SRCS= linux_elf32.c linux_fork.c linux${SFX}_dummy_machdep.c linux_file.c linux_event.c \
linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
linux${SFX}_machdep.c linux_misc.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux${SFX}_sysent.c \
Index: sys/modules/linux64/Makefile
===================================================================
--- sys/modules/linux64/Makefile
+++ sys/modules/linux64/Makefile
@@ -8,7 +8,7 @@
VDSO= linux_vdso
KMOD= linux64
-SRCS= linux_fork.c linux_dummy_machdep.c linux_file.c linux_event.c \
+SRCS= linux_elf64.c linux_fork.c linux_dummy_machdep.c linux_file.c linux_event.c \
linux_futex.c linux_getcwd.c linux_ioctl.c linux_ipc.c \
linux_machdep.c linux_misc.c linux_ptrace.c linux_signal.c \
linux_socket.c linux_stats.c linux_sysctl.c linux_sysent.c \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Nov 22, 6:21 AM (19 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25924608
Default Alt Text
D30019.id90712.diff (24 KB)
Attached To
Mode
D30019: linux(4): implement coredump support
Attached
Detach File
Event Timeline
Log In to Comment