1/*-
2 * Copyright (c) 2000 David O'Brien
3 * Copyright (c) 1995-1996 S�ren Schmidt
4 * Copyright (c) 1996 Peter Wemm
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
--- 15 unchanged lines hidden (view full) ---
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/kern/imgact_elf.c 196512 2009-08-24 16:19:47Z bz $");
33
34#include "opt_compat.h"
35
36#include <sys/param.h>
37#include <sys/exec.h>
38#include <sys/fcntl.h>
39#include <sys/imgact.h>
40#include <sys/imgact_elf.h>
--- 40 unchanged lines hidden (view full) ---
81static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
82 const char *interp, int32_t *osrel);
83static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
84 u_long *entry, size_t pagesize);
85static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object,
86 vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
87 vm_prot_t prot, size_t pagesize);
88static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp);
89static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note,
90 int32_t *osrel);
91static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel);
92static boolean_t __elfN(check_note)(struct image_params *imgp,
93 Elf_Brandnote *checknote, int32_t *osrel);
94
95SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0,
96 "");
97
98int __elfN(fallback_brand) = -1;
99SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO,
--- 14 unchanged lines hidden (view full) ---
114
115static const char FREEBSD_ABI_VENDOR[] = "FreeBSD";
116
117Elf_Brandnote __elfN(freebsd_brandnote) = {
118 .hdr.n_namesz = sizeof(FREEBSD_ABI_VENDOR),
119 .hdr.n_descsz = sizeof(int32_t),
120 .hdr.n_type = 1,
121 .vendor = FREEBSD_ABI_VENDOR,
122 .flags = BN_TRANSLATE_OSREL,
123 .trans_osrel = __elfN(freebsd_trans_osrel)
124};
125
126static boolean_t
127__elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel)
128{
129 uintptr_t p;
130
131 p = (uintptr_t)(note + 1);
132 p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
133 *osrel = *(const int32_t *)(p);
134
135 return (TRUE);
136}
137
138static const char GNU_ABI_VENDOR[] = "GNU";
139static int GNU_KFREEBSD_ABI_DESC = 3;
140
141Elf_Brandnote __elfN(kfreebsd_brandnote) = {
142 .hdr.n_namesz = sizeof(GNU_ABI_VENDOR),
143 .hdr.n_descsz = 16, /* XXX at least 16 */
144 .hdr.n_type = 1,
145 .vendor = GNU_ABI_VENDOR,
146 .flags = BN_TRANSLATE_OSREL,
147 .trans_osrel = kfreebsd_trans_osrel
148};
149
150static boolean_t
151kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel)
152{
153 const Elf32_Word *desc;
154 uintptr_t p;
155
156 p = (uintptr_t)(note + 1);
157 p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
158
159 desc = (const Elf32_Word *)p;
160 if (desc[0] != GNU_KFREEBSD_ABI_DESC)
161 return (FALSE);
162
163 /*
164 * Debian GNU/kFreeBSD embed the earliest compatible kernel version
165 * (__FreeBSD_version: <major><two digit minor>Rxx) in the LSB way.
166 */
167 *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3];
168
169 return (TRUE);
170}
171
172int
173__elfN(insert_brand_entry)(Elf_Brandinfo *entry)
174{
175 int i;
176
177 for (i = 0; i < MAX_BRANDS; i++) {
178 if (elf_brand_list[i] == NULL) {
179 elf_brand_list[i] = entry;
--- 1236 unchanged lines hidden (view full) ---
1416 if (strncmp(checknote->vendor, note_name,
1417 checknote->hdr.n_namesz) != 0)
1418 goto nextnote;
1419
1420 /*
1421 * Fetch the osreldate for binary
1422 * from the ELF OSABI-note if necessary.
1423 */
1424 if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 &&
1425 checknote->trans_osrel != NULL)
1426 return (checknote->trans_osrel(note, osrel));
1427 return (TRUE);
1428
1429nextnote:
1430 note = (const Elf_Note *)((const char *)(note + 1) +
1431 roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
1432 roundup2(note->n_descsz, sizeof(Elf32_Addr)));
1433 }
1434
1435 return (FALSE);
1436}
1437
1438/*
1439 * Tell kern_execve.c about it, with a little help from the linker.
1440 */
1441static struct execsw __elfN(execsw) = {
1442 __CONCAT(exec_, __elfN(imgact)),
1443 __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
1444};
1445EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw));
2 * Copyright (c) 2000 David O'Brien
3 * Copyright (c) 1995-1996 S�ren Schmidt
4 * Copyright (c) 1996 Peter Wemm
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
--- 15 unchanged lines hidden (view full) ---
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/kern/imgact_elf.c 196512 2009-08-24 16:19:47Z bz $");
33
34#include "opt_compat.h"
35
36#include <sys/param.h>
37#include <sys/exec.h>
38#include <sys/fcntl.h>
39#include <sys/imgact.h>
40#include <sys/imgact_elf.h>
--- 40 unchanged lines hidden (view full) ---
81static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
82 const char *interp, int32_t *osrel);
83static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
84 u_long *entry, size_t pagesize);
85static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object,
86 vm_offset_t offset, caddr_t vmaddr, size_t memsz, size_t filsz,
87 vm_prot_t prot, size_t pagesize);
88static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp);
89static boolean_t __elfN(freebsd_trans_osrel)(const Elf_Note *note,
90 int32_t *osrel);
91static boolean_t kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel);
92static boolean_t __elfN(check_note)(struct image_params *imgp,
93 Elf_Brandnote *checknote, int32_t *osrel);
94
95SYSCTL_NODE(_kern, OID_AUTO, __CONCAT(elf, __ELF_WORD_SIZE), CTLFLAG_RW, 0,
96 "");
97
98int __elfN(fallback_brand) = -1;
99SYSCTL_INT(__CONCAT(_kern_elf, __ELF_WORD_SIZE), OID_AUTO,
--- 14 unchanged lines hidden (view full) ---
114
115static const char FREEBSD_ABI_VENDOR[] = "FreeBSD";
116
117Elf_Brandnote __elfN(freebsd_brandnote) = {
118 .hdr.n_namesz = sizeof(FREEBSD_ABI_VENDOR),
119 .hdr.n_descsz = sizeof(int32_t),
120 .hdr.n_type = 1,
121 .vendor = FREEBSD_ABI_VENDOR,
122 .flags = BN_TRANSLATE_OSREL,
123 .trans_osrel = __elfN(freebsd_trans_osrel)
124};
125
126static boolean_t
127__elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel)
128{
129 uintptr_t p;
130
131 p = (uintptr_t)(note + 1);
132 p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
133 *osrel = *(const int32_t *)(p);
134
135 return (TRUE);
136}
137
138static const char GNU_ABI_VENDOR[] = "GNU";
139static int GNU_KFREEBSD_ABI_DESC = 3;
140
141Elf_Brandnote __elfN(kfreebsd_brandnote) = {
142 .hdr.n_namesz = sizeof(GNU_ABI_VENDOR),
143 .hdr.n_descsz = 16, /* XXX at least 16 */
144 .hdr.n_type = 1,
145 .vendor = GNU_ABI_VENDOR,
146 .flags = BN_TRANSLATE_OSREL,
147 .trans_osrel = kfreebsd_trans_osrel
148};
149
150static boolean_t
151kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel)
152{
153 const Elf32_Word *desc;
154 uintptr_t p;
155
156 p = (uintptr_t)(note + 1);
157 p += roundup2(note->n_namesz, sizeof(Elf32_Addr));
158
159 desc = (const Elf32_Word *)p;
160 if (desc[0] != GNU_KFREEBSD_ABI_DESC)
161 return (FALSE);
162
163 /*
164 * Debian GNU/kFreeBSD embed the earliest compatible kernel version
165 * (__FreeBSD_version: <major><two digit minor>Rxx) in the LSB way.
166 */
167 *osrel = desc[1] * 100000 + desc[2] * 1000 + desc[3];
168
169 return (TRUE);
170}
171
172int
173__elfN(insert_brand_entry)(Elf_Brandinfo *entry)
174{
175 int i;
176
177 for (i = 0; i < MAX_BRANDS; i++) {
178 if (elf_brand_list[i] == NULL) {
179 elf_brand_list[i] = entry;
--- 1236 unchanged lines hidden (view full) ---
1416 if (strncmp(checknote->vendor, note_name,
1417 checknote->hdr.n_namesz) != 0)
1418 goto nextnote;
1419
1420 /*
1421 * Fetch the osreldate for binary
1422 * from the ELF OSABI-note if necessary.
1423 */
1424 if ((checknote->flags & BN_TRANSLATE_OSREL) != 0 &&
1425 checknote->trans_osrel != NULL)
1426 return (checknote->trans_osrel(note, osrel));
1427 return (TRUE);
1428
1429nextnote:
1430 note = (const Elf_Note *)((const char *)(note + 1) +
1431 roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
1432 roundup2(note->n_descsz, sizeof(Elf32_Addr)));
1433 }
1434
1435 return (FALSE);
1436}
1437
1438/*
1439 * Tell kern_execve.c about it, with a little help from the linker.
1440 */
1441static struct execsw __elfN(execsw) = {
1442 __CONCAT(exec_, __elfN(imgact)),
1443 __XSTRING(__CONCAT(ELF, __ELF_WORD_SIZE))
1444};
1445EXEC_SET(__CONCAT(elf, __ELF_WORD_SIZE), __elfN(execsw));