1352e51dimp/*-
2e75d1bepfg * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3e75d1bepfg *
4352e51dimp * Copyright 1996-1998 John D. Polstra.
5352e51dimp * All rights reserved.
6352e51dimp *
7352e51dimp * Redistribution and use in source and binary forms, with or without
8352e51dimp * modification, are permitted provided that the following conditions
9352e51dimp * are met:
10352e51dimp * 1. Redistributions of source code must retain the above copyright
11352e51dimp *    notice, this list of conditions and the following disclaimer.
12352e51dimp * 2. Redistributions in binary form must reproduce the above copyright
13352e51dimp *    notice, this list of conditions and the following disclaimer in the
14352e51dimp *    documentation and/or other materials provided with the distribution.
15352e51dimp *
16352e51dimp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17352e51dimp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18352e51dimp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19352e51dimp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20352e51dimp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21352e51dimp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22352e51dimp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23352e51dimp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24352e51dimp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25352e51dimp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26352e51dimp *
27352e51dimp *	from: src/sys/i386/i386/elf_machdep.c,v 1.20 2004/08/11 02:35:05 marcel
28352e51dimp */
29352e51dimp
30352e51dimp#include <sys/cdefs.h>
31352e51dimp__FBSDID("$FreeBSD$");
32352e51dimp
33352e51dimp#include <sys/param.h>
34352e51dimp#include <sys/kernel.h>
35352e51dimp#include <sys/systm.h>
36352e51dimp#include <sys/exec.h>
37352e51dimp#include <sys/imgact.h>
38352e51dimp#include <sys/linker.h>
39352e51dimp#include <sys/sysent.h>
40352e51dimp#include <sys/imgact_elf.h>
414208ccbkib#include <sys/proc.h>
42352e51dimp#include <sys/syscall.h>
43352e51dimp#include <sys/signalvar.h>
44352e51dimp#include <sys/vnode.h>
45352e51dimp
46352e51dimp#include <vm/vm.h>
47352e51dimp#include <vm/pmap.h>
48352e51dimp#include <vm/vm_param.h>
49352e51dimp
50352e51dimp#include <machine/elf.h>
51352e51dimp#include <machine/md_var.h>
52aa07cd3neel#include <machine/cache.h>
53352e51dimp
54a593801jhbstatic struct sysentvec elf_freebsd_sysvec = {
5590552e4imp	.sv_size	= SYS_MAXSYSCALL,
5690552e4imp	.sv_table	= sysent,
5790552e4imp	.sv_errsize	= 0,
5890552e4imp	.sv_errtbl	= NULL,
5990552e4imp	.sv_transtrap	= NULL,
6090552e4imp	.sv_fixup	= __elfN(freebsd_fixup),
6190552e4imp	.sv_sendsig	= sendsig,
6290552e4imp	.sv_sigcode	= sigcode,
6390552e4imp	.sv_szsigcode	= &szsigcode,
64a593801jhb#ifdef __mips_n64
6590552e4imp	.sv_name	= "FreeBSD ELF64",
6690552e4imp#else
67c500808kib	.sv_name	= "FreeBSD ELF32",
68a593801jhb#endif
69c500808kib	.sv_coredump	= __elfN(coredump),
70c500808kib	.sv_imgact_try	= NULL,
71c500808kib	.sv_minsigstksz	= MINSIGSTKSZ,
72c500808kib	.sv_minuser	= VM_MIN_ADDRESS,
73c500808kib	.sv_maxuser	= VM_MAXUSER_ADDRESS,
74c500808kib	.sv_usrstack	= USRSTACK,
75c500808kib	.sv_psstrings	= PS_STRINGS,
76c500808kib	.sv_stackprot	= VM_PROT_ALL,
773f50cb7jhb	.sv_copyout_auxargs = __elfN(freebsd_copyout_auxargs),
78c500808kib	.sv_copyout_strings = exec_copyout_strings,
79c500808kib	.sv_setregs	= exec_setregs,
80c500808kib	.sv_fixlimit	= NULL,
818fad228kib	.sv_maxssiz	= NULL,
82a593801jhb#ifdef __mips_n64
83a593801jhb	.sv_flags	= SV_ABI_FREEBSD | SV_LP64 | SV_ASLR,
84a593801jhb#else
850af6ee1kib	.sv_flags	= SV_ABI_FREEBSD | SV_ILP32 | SV_ASLR,
86a593801jhb#endif
874208ccbkib	.sv_set_syscall_retval = cpu_set_syscall_retval,
88ab59605kib	.sv_fetch_syscall_args = cpu_fetch_syscall_args,
894208ccbkib	.sv_syscallnames = syscallnames,
9069b8756dchagin	.sv_schedtail	= NULL,
91ca0fda4dchagin	.sv_thread_detach = NULL,
92e706df7dchagin	.sv_trap	= NULL,
93352e51dimp};
94352e51dimp
95a593801jhbstatic __ElfN(Brandinfo) freebsd_brand_info = {
96c500808kib	.brand		= ELFOSABI_FREEBSD,
97c500808kib	.machine	= EM_MIPS,
98c500808kib	.compat_3_brand	= "FreeBSD",
99c500808kib	.emul_path	= NULL,
100c500808kib	.interp_path	= "/libexec/ld-elf.so.1",
101a593801jhb	.sysvec		= &elf_freebsd_sysvec,
102c500808kib	.interp_newpath	= NULL,
103a593801jhb	.brand_note	= &__elfN(freebsd_brandnote),
104519d947jhb	.flags		= BI_CAN_EXEC_DYN | BI_BRAND_NOTE
105c500808kib};
106352e51dimp
107a593801jhbSYSINIT(elf, SI_SUB_EXEC, SI_ORDER_ANY,
108a593801jhb    (sysinit_cfunc_t) __elfN(insert_brand_entry),
109c500808kib    &freebsd_brand_info);
110352e51dimp
111352e51dimpvoid
112a593801jhb__elfN(dump_thread)(struct thread *td __unused, void *dst __unused,
113352e51dimp    size_t *off __unused)
114352e51dimp{
115352e51dimp}
116352e51dimp
1170517fffadrian/*
1180517fffadrian * The following MIPS relocation code for tracking multiple
1190517fffadrian * consecutive HI32/LO32 entries is because of the following:
1200517fffadrian *
1210517fffadrian * https://dmz-portal.mips.com/wiki/MIPS_relocation_types
1220517fffadrian *
1230517fffadrian * ===
1240517fffadrian *
1250517fffadrian * + R_MIPS_HI16
1260517fffadrian *
1270517fffadrian * An R_MIPS_HI16 must be followed eventually by an associated R_MIPS_LO16
1280517fffadrian * relocation record in the same SHT_REL section. The contents of the two
1290517fffadrian * fields to be relocated are combined to form a full 32-bit addend AHL.
1300517fffadrian * An R_MIPS_LO16 entry which does not immediately follow a R_MIPS_HI16 is
1310517fffadrian * combined with the most recent one encountered, i.e. multiple R_MIPS_LO16
1320517fffadrian * entries may be associated with a single R_MIPS_HI16. Use of these
1330517fffadrian * relocation types in a SHT_REL section is discouraged and may be
1340517fffadrian * forbidden to avoid this complication.
1350517fffadrian *
1360517fffadrian * A GNU extension allows multiple R_MIPS_HI16 records to share the same
1370517fffadrian * R_MIPS_LO16 relocation record(s). The association works like this within
1380517fffadrian * a single relocation section:
1390517fffadrian *
1400517fffadrian * + From the beginning of the section moving to the end of the section,
1410517fffadrian *   until R_MIPS_LO16 is not found each found R_MIPS_HI16 relocation will
1420517fffadrian *   be associated with the first R_MIPS_LO16.
1430517fffadrian *
1440517fffadrian * + Until another R_MIPS_HI16 record is found all found R_MIPS_LO16
1450517fffadrian *   relocations found are associated with the last R_MIPS_HI16.
1460517fffadrian *
147