Hi, please, look a patch bellow. kern/118473 related. any comments, help :) Implement new way of branding ELF binaries by looking to a ".note.ABI-tag" section. For what handler .brand_abi_note in Elf_Brandinfo is added. The search order of a brand is changed, now first of all the ".note.ABI-tag" is looked through. Implement .brand_abi_note handler for FreeBSD and Linux binaries. Move code which fetch osreldate for FreeBSD binaries to corresponding handler. Add new branding flag BI_CAN_EXEC_INTERP, which is used if the ABI allows interpreter start (as executable). Implement corresponding handler. diff --git a/sys/amd64/amd64/elf_machdep.c b/sys/amd64/amd64/elf_machdep.c index 4f6d178..0aea61d 100644 --- a/sys/amd64/amd64/elf_machdep.c +++ b/sys/amd64/amd64/elf_machdep.c _at__at_ -84,7 +84,8 _at__at_ static Elf64_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, _at__at_ -99,7 +100,8 _at__at_ static Elf64_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index de60744..339bc38 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c _at__at_ -42,6 +42,7 _at__at_ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/systm.h> +#include <sys/elf.h> #include <sys/exec.h> #include <sys/fcntl.h> #include <sys/imgact.h> _at__at_ -93,6 +94,8 _at__at_ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); suword32(pos++, val); \ } while (0) +#define aligned(a, t) (rounddown((unsigned long)(a), sizeof(t)) == (unsigned long)(a)) + #if BYTE_ORDER == LITTLE_ENDIAN #define SHELLMAGIC 0x2123 /* #! */ #else _at__at_ -999,6 +1002,54 _at__at_ linux32_fixlimit(struct rlimit *rl, int which) } } +static const char GNULINUX_ABI_VENDOR[] = "GNU"; +static const int GNULINUX_ABI_LEN = 16; + +static int +linux32_abi_note(struct image_params *imgp, int32_t *osrel) +{ + const Elf_Note *note, *note_end; + const Elf32_Phdr *phdr, *pnote; + const Elf32_Ehdr *hdr; + const char *note_name; + int i; + + pnote = NULL; + hdr = (const Elf32_Ehdr *)imgp->image_header; + phdr = (const Elf32_Phdr *)(imgp->image_header + hdr->e_phoff); + + for (i = 0; i < hdr->e_phnum; i++) + if (phdr[i].p_type == PT_NOTE) { + pnote = &phdr[i]; + break; + } + + if (pnote == NULL || pnote->p_offset >= PAGE_SIZE || + pnote->p_offset + pnote->p_filesz >= PAGE_SIZE) + return (0); + + note = (const Elf_Note *)(imgp->image_header + pnote->p_offset); + if (!aligned(note, uint32_t)) + return (0); + note_end = (const Elf_Note *)(hdr + pnote->p_offset + + pnote->p_filesz); + while (note < note_end) { + if (note->n_namesz == sizeof(GNULINUX_ABI_VENDOR) && + note->n_descsz == GNULINUX_ABI_LEN && + note->n_type == 1 /* ABI_NOTETYPE */) { + note_name = (const char *)(note + 1); + if (strncmp(GNULINUX_ABI_VENDOR, note_name, + sizeof(GNULINUX_ABI_VENDOR)) == 0) + return(1); + } + note = (const Elf_Note *)((const char *)(note + 1) + + roundup2(note->n_namesz, sizeof(Elf32_Addr)) + + roundup2(note->n_descsz, sizeof(Elf32_Addr))); + } + + return (0); +} + struct sysentvec elf_linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, .sv_table = linux_sysent, _at__at_ -1038,7 +1089,8 _at__at_ static Elf32_Brandinfo linux_brand = { .interp_path = "/lib/ld-linux.so.1", .sysvec = &elf_linux_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = linux32_abi_note, + .flags = BI_CAN_EXEC_DYN | BI_CAN_EXEC_INTERP }; static Elf32_Brandinfo linux_glibc2brand = { _at__at_ -1049,7 +1101,8 _at__at_ static Elf32_Brandinfo linux_glibc2brand = { .interp_path = "/lib/ld-linux.so.2", .sysvec = &elf_linux_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = linux32_abi_note, + .flags = BI_CAN_EXEC_DYN | BI_CAN_EXEC_INTERP }; Elf32_Brandinfo *linux_brandlist[] = { diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index 693eab1..e65f947 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c _at__at_ -84,7 +84,8 _at__at_ static Elf32_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, _at__at_ -99,7 +100,8 _at__at_ static Elf32_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/compat/ia32/ia32_sysvec.c b/sys/compat/ia32/ia32_sysvec.c index 0b32b9a..92b990a 100644 --- a/sys/compat/ia32/ia32_sysvec.c +++ b/sys/compat/ia32/ia32_sysvec.c _at__at_ -148,6 +148,7 _at__at_ static Elf32_Brandinfo ia32_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &ia32_freebsd_sysvec, .interp_newpath = "/libexec/ld-elf32.so.1", + .brand_abi_note = __elfN(freebsd_abi_note), .flags = BI_CAN_EXEC_DYN }; _at__at_ -163,7 +164,8 _at__at_ static Elf32_Brandinfo ia32_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &ia32_freebsd_sysvec, .interp_newpath = "/libexec/ld-elf32.so.1", - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oia32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/compat/svr4/svr4_sysvec.c b/sys/compat/svr4/svr4_sysvec.c index 0030e3a..a406576 100644 --- a/sys/compat/svr4/svr4_sysvec.c +++ b/sys/compat/svr4/svr4_sysvec.c _at__at_ -204,6 +204,7 _at__at_ Elf32_Brandinfo svr4_brand = { .interp_path = "/lib/libc.so.1", .sysvec = &svr4_sysvec, .interp_newpath = NULL, + .brand_abi_note = NULL, .flags = 0 }; diff --git a/sys/i386/i386/elf_machdep.c b/sys/i386/i386/elf_machdep.c index 19eddd0..593f9bd 100644 --- a/sys/i386/i386/elf_machdep.c +++ b/sys/i386/i386/elf_machdep.c _at__at_ -84,7 +84,8 _at__at_ static Elf32_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, _at__at_ -99,7 +100,8 _at__at_ static Elf32_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 66cb336..c3f1e84 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c _at__at_ -91,6 +91,7 _at__at_ MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures"); #define fldcw(addr) __asm("fldcw %0" : : "m" (*(addr))) #define __LINUX_NPXCW__ 0x37f +#define aligned(a, t) (rounddown((unsigned long)(a), sizeof(t)) == (unsigned long)(a)) extern char linux_sigcode[]; extern int linux_szsigcode; _at__at_ -964,6 +965,53 _at__at_ linux_get_machine(const char **dst) return (0); } +static const char GNULINUX_ABI_VENDOR[] = "GNU"; +static const int GNULINUX_ABI_LEN = 16; + +static int +linux_abi_note(struct image_params *imgp, int32_t *osrel) +{ + const Elf_Note *note, *note_end; + const Elf32_Phdr *phdr, *pnote; + const Elf32_Ehdr *hdr; + const char *note_name; + int i; + + pnote = NULL; + hdr = (const Elf32_Ehdr *)imgp->image_header; + phdr = (const Elf32_Phdr *)(imgp->image_header + hdr->e_phoff); + + for (i = 0; i < hdr->e_phnum; i++) + if (phdr[i].p_type == PT_NOTE) { + pnote = &phdr[i]; + break; + } + if (pnote == NULL || pnote->p_offset >= PAGE_SIZE || + pnote->p_offset + pnote->p_filesz >= PAGE_SIZE) + return (0); + + note = (const Elf_Note *)(imgp->image_header + pnote->p_offset); + if (!aligned(note, uint32_t)) + return (0); + note_end = (const Elf_Note *)(hdr + pnote->p_offset + + pnote->p_filesz); + while (note < note_end) { + if (note->n_namesz == sizeof(GNULINUX_ABI_VENDOR) && + note->n_descsz == GNULINUX_ABI_LEN && + note->n_type == 1 /* ABI_NOTETYPE */) { + note_name = (const char *)(note + 1); + if (strncmp(GNULINUX_ABI_VENDOR, note_name, + sizeof(GNULINUX_ABI_VENDOR)) == 0) + return(1); + } + note = (const Elf_Note *)((const char *)(note + 1) + + roundup2(note->n_namesz, sizeof(Elf32_Addr)) + + roundup2(note->n_descsz, sizeof(Elf32_Addr))); + } + + return (0); +} + struct sysentvec linux_sysvec = { .sv_size = LINUX_SYS_MAXSYSCALL, _at__at_ -1035,7 +1083,8 _at__at_ static Elf32_Brandinfo linux_brand = { .interp_path = "/lib/ld-linux.so.1", .sysvec = &elf_linux_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = linux_abi_note, + .flags = BI_CAN_EXEC_DYN | BI_CAN_EXEC_INTERP }; static Elf32_Brandinfo linux_glibc2brand = { _at__at_ -1046,7 +1095,8 _at__at_ static Elf32_Brandinfo linux_glibc2brand = { .interp_path = "/lib/ld-linux.so.2", .sysvec = &elf_linux_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = linux_abi_note, + .flags = BI_CAN_EXEC_DYN | BI_CAN_EXEC_INTERP }; Elf32_Brandinfo *linux_brandlist[] = { diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index a3a6e57..a0289de 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c _at__at_ -92,7 +92,8 _at__at_ static Elf64_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_info); _at__at_ -105,7 +106,8 _at__at_ static Elf64_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, (sysinit_cfunc_t)elf64_insert_brand_entry, &freebsd_brand_oinfo); diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 431ee38..c970291 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c _at__at_ -78,8 +78,8 _at__at_ __FBSDID("$FreeBSD$"); #define OLD_EI_BRAND 8 static int __elfN(check_header)(const Elf_Ehdr *hdr); -static Elf_Brandinfo *__elfN(get_brandinfo)(const Elf_Ehdr *hdr, - const char *interp); +static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp, + const char *interp, int32_t *osrel); static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr, u_long *entry, size_t pagesize); static int __elfN(load_section)(struct vmspace *vmspace, vm_object_t object, _at__at_ -158,19 +158,31 _at__at_ __elfN(brand_inuse)(Elf_Brandinfo *entry) } static Elf_Brandinfo * -__elfN(get_brandinfo)(const Elf_Ehdr *hdr, const char *interp) +__elfN(get_brandinfo)(struct image_params *imgp, const char *interp, + int32_t *osrel) { + const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; Elf_Brandinfo *bi; + int ret, fname_len, interp_len; int i; /* - * We support three types of branding -- (1) the ELF EI_OSABI field + * We support four types of branding -- (1) the ELF EI_OSABI field * that SCO added to the ELF spec, (2) FreeBSD 3.x's traditional string - * branding w/in the ELF header, and (3) path of the `interp_path' - * field. We should also look for an ".note.ABI-tag" ELF section now - * in all Linux ELF binaries, FreeBSD 4.1+, and some NetBSD ones. + * branding w/in the ELF header, (3) path of the `interp_path' + * field, and (4) the ".note.ABI-tag" ELF section. */ + /* Look for an ".note.ABI-tag" ELF section */ + for (i = 0; i < MAX_BRANDS; i++) { + bi = elf_brand_list[i]; + if (bi != NULL && hdr->e_machine == bi->machine && bi->brand_abi_note) { + ret = (*bi->brand_abi_note)(imgp, osrel); + if (ret) + return (bi); + } + } + /* If the executable has a brand, search for it in the brand list. */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; _at__at_ -191,6 +203,23 _at__at_ __elfN(get_brandinfo)(const Elf_Ehdr *hdr, const char *interp) } } + /* Some ABI (Linux) allow to run the interpreter. */ + for (i = 0; i < MAX_BRANDS; i++) { + bi = elf_brand_list[i]; + if (bi == NULL || hdr->e_machine != bi->machine || + (bi->flags & BI_CAN_EXEC_INTERP) == 0) + continue; + + fname_len = strlen(imgp->args->fname); + interp_len = strlen(bi->interp_path); + if (fname_len < interp_len) + continue; + ret = strncmp(imgp->args->fname + (fname_len - interp_len), + bi->interp_path, interp_len); + if (ret == 0) + return (bi); + } + /* Lacking a recognized interpreter, try the default brand */ for (i = 0; i < MAX_BRANDS; i++) { bi = elf_brand_list[i]; _at__at_ -590,13 +619,11 _at__at_ fail: return (error); } -static const char FREEBSD_ABI_VENDOR[] = "FreeBSD"; - static int __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) { const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; - const Elf_Phdr *phdr, *pnote = NULL; + const Elf_Phdr *phdr; Elf_Auxargs *elf_auxargs; struct vmspace *vmspace; vm_prot_t prot; _at__at_ -604,12 +631,11 _at__at_ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) u_long text_addr = 0, data_addr = 0; u_long seg_size, seg_addr; u_long addr, entry = 0, proghdr = 0; + int32_t osrel = 0; int error = 0, i; const char *interp = NULL, *newinterp = NULL; Elf_Brandinfo *brand_info; - const Elf_Note *note, *note_end; char *path; - const char *note_name; struct sysentvec *sv; /* _at__at_ -646,7 +672,7 _at__at_ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) } } - brand_info = __elfN(get_brandinfo)(hdr, interp); + brand_info = __elfN(get_brandinfo)(imgp, interp, &osrel); if (brand_info == NULL) { uprintf("ELF binary type \"%u\" not known.\n", hdr->e_ident[EI_OSABI]); _at__at_ -750,9 +776,6 _at__at_ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) case PT_PHDR: /* Program header table info */ proghdr = phdr[i].p_vaddr; break; - case PT_NOTE: - pnote = &phdr[i]; - break; default: break; } _at__at_ -839,41 +862,7 _at__at_ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) imgp->auxargs = elf_auxargs; imgp->interpreted = 0; - - /* - * Try to fetch the osreldate for FreeBSD binary from the ELF - * OSABI-note. Only the first page of the image is searched, - * the same as for headers. - */ - if (pnote != NULL && pnote->p_offset < PAGE_SIZE && - pnote->p_offset + pnote->p_filesz < PAGE_SIZE ) { - note = (const Elf_Note *)(imgp->image_header + pnote->p_offset); - if (!aligned(note, Elf32_Addr)) { - free(imgp->auxargs, M_TEMP); - imgp->auxargs = NULL; - return (ENOEXEC); - } - note_end = (const Elf_Note *)(imgp->image_header + pnote->p_offset + - pnote->p_filesz); - while (note < note_end) { - if (note->n_namesz == sizeof(FREEBSD_ABI_VENDOR) && - note->n_descsz == sizeof(int32_t) && - note->n_type == 1 /* ABI_NOTETYPE */) { - note_name = (const char *)(note + 1); - if (strncmp(FREEBSD_ABI_VENDOR, note_name, - sizeof(FREEBSD_ABI_VENDOR)) == 0) { - imgp->proc->p_osrel = *(const int32_t *) - (note_name + - round_page_ps(sizeof(FREEBSD_ABI_VENDOR), - sizeof(Elf32_Addr))); - break; - } - } - note = (const Elf_Note *)((const char *)(note + 1) + - round_page_ps(note->n_namesz, sizeof(Elf32_Addr)) + - round_page_ps(note->n_descsz, sizeof(Elf32_Addr))); - } - } + imgp->proc->p_osrel = osrel; return (error); } _at__at_ -1334,6 +1323,63 _at__at_ __elfN(putnote)(void *dst, size_t *off, const char *name, int type, *off += roundup2(note.n_descsz, sizeof(Elf_Size)); } +static const char FREEBSD_ABI_VENDOR[] = "FreeBSD"; + +int +__elfN(freebsd_abi_note)(struct image_params *imgp, int32_t *osrel) +{ + const Elf_Note *note, *note_end; + const Elf32_Phdr *phdr, *pnote; + const Elf32_Ehdr *hdr; + const char *note_name; + int i; + + pnote = NULL; + hdr = (const Elf32_Ehdr *)imgp->image_header; + phdr = (const Elf32_Phdr *)(imgp->image_header + hdr->e_phoff); + + for (i = 0; i < hdr->e_phnum; i++) + if (phdr[i].p_type == PT_NOTE) { + pnote = &phdr[i]; + break; + } + + if (pnote == NULL || pnote->p_offset >= PAGE_SIZE || + pnote->p_offset + pnote->p_filesz >= PAGE_SIZE) + return (0); + + note = (const Elf_Note *)(imgp->image_header + pnote->p_offset); + if (!aligned(note, uint32_t)) + return (0); + note_end = (const Elf_Note *)(hdr + pnote->p_offset + + pnote->p_filesz); + while (note < note_end) { + if (note->n_namesz == sizeof(FREEBSD_ABI_VENDOR) && + note->n_descsz == sizeof(int32_t) && + note->n_type == 1 /* ABI_NOTETYPE */) { + note_name = (const char *)(note + 1); + if (strncmp(FREEBSD_ABI_VENDOR, note_name, + sizeof(FREEBSD_ABI_VENDOR)) != 0) + continue; + /* + * Fetch the osreldate for FreeBSD binary + * from the ELF OSABI-note. + */ + if (osrel != NULL) + *osrel = *(const int32_t *) + (note_name + + round_page_ps(sizeof(FREEBSD_ABI_VENDOR), + sizeof(Elf32_Addr))); + return(1); + } + note = (const Elf_Note *)((const char *)(note + 1) + + round_page_ps(note->n_namesz, sizeof(Elf32_Addr)) + + round_page_ps(note->n_descsz, sizeof(Elf32_Addr))); + } + + return (0); +} + /* * Tell kern_execve.c about it, with a little help from the linker. */ diff --git a/sys/mips/mips/elf_machdep.c b/sys/mips/mips/elf_machdep.c index 163d0ee..807ae67 100644 --- a/sys/mips/mips/elf_machdep.c +++ b/sys/mips/mips/elf_machdep.c _at__at_ -86,6 +86,8 _at__at_ static Elf32_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, + .brand_abi_note = NULL, + .brand_abi_note = NULL, .flags = 0 }; diff --git a/sys/powerpc/powerpc/elf_machdep.c b/sys/powerpc/powerpc/elf_machdep.c index 69ac55b..f0dc474 100644 --- a/sys/powerpc/powerpc/elf_machdep.c +++ b/sys/powerpc/powerpc/elf_machdep.c _at__at_ -87,7 +87,8 _at__at_ static Elf32_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_ANY, _at__at_ -102,7 +103,8 _at__at_ static Elf32_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf32_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf32, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/sparc64/sparc64/elf_machdep.c b/sys/sparc64/sparc64/elf_machdep.c index a956c5c..03b9056 100644 --- a/sys/sparc64/sparc64/elf_machdep.c +++ b/sys/sparc64/sparc64/elf_machdep.c _at__at_ -99,7 +99,8 _at__at_ static Elf64_Brandinfo freebsd_brand_info = { .interp_path = "/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY, _at__at_ -114,7 +115,8 _at__at_ static Elf64_Brandinfo freebsd_brand_oinfo = { .interp_path = "/usr/libexec/ld-elf.so.1", .sysvec = &elf64_freebsd_sysvec, .interp_newpath = NULL, - .flags = BI_CAN_EXEC_DYN, + .brand_abi_note = __elfN(freebsd_abi_note), + .flags = BI_CAN_EXEC_DYN }; SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index deb5b10..d290185 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h _at__at_ -62,8 +62,10 _at__at_ typedef struct { const char *interp_path; struct sysentvec *sysvec; const char *interp_newpath; + int (*brand_abi_note)(struct image_params *, int32_t *); int flags; -#define BI_CAN_EXEC_DYN 0x0001 +#define BI_CAN_EXEC_DYN 0x0001 +#define BI_CAN_EXEC_INTERP 0x0002 } __ElfN(Brandinfo); __ElfType(Auxargs); _at__at_ -76,6 +78,7 _at__at_ int __elfN(insert_brand_entry)(Elf_Brandinfo *entry); int __elfN(remove_brand_entry)(Elf_Brandinfo *entry); int __elfN(freebsd_fixup)(register_t **, struct image_params *); int __elfN(coredump)(struct thread *, struct vnode *, off_t); +int __elfN(freebsd_abi_note)(struct image_params *, int32_t *); /* Machine specific function to dump per-thread information. */ void __elfN(dump_thread)(struct thread *, void *, size_t *); -- Have fun! chdReceived on Tue Jan 06 2009 - 12:14:20 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:40 UTC