From feb2aba5b692eb1c9cb8275d405791736ea1067e Mon Sep 17 00:00:00 2001 From: kib Date: Tue, 4 Dec 2007 12:28:07 +0000 Subject: Implement fetching of the __FreeBSD_version from the ELF ABI-tag note. The value is read into the p_osrel member of the struct proc. p_osrel is set to 0 for the binaries without the note. MFC after: 3 days --- sys/kern/imgact_elf.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'sys/kern/imgact_elf.c') diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index ab6ab03..03da355 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -597,11 +597,13 @@ 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; + const Elf_Phdr *phdr, *pnote = NULL; Elf_Auxargs *elf_auxargs; struct vmspace *vmspace; vm_prot_t prot; @@ -612,7 +614,9 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp) int error = 0, i; const char *interp = NULL; Elf_Brandinfo *brand_info; + const Elf_Note *note, *note_end; char *path; + const char *note_name; struct thread *td = curthread; struct sysentvec *sv; @@ -754,6 +758,9 @@ __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; } @@ -835,6 +842,41 @@ __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))); + } + } + return (error); } @@ -901,8 +943,6 @@ static void __elfN(puthdr)(struct thread *, void *, size_t *, int); static void __elfN(putnote)(void *, size_t *, const char *, int, const void *, size_t); -extern int osreldate; - int __elfN(coredump)(td, vp, limit) struct thread *td; -- cgit v1.1