summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2007-12-04 12:28:07 +0000
committerkib <kib@FreeBSD.org>2007-12-04 12:28:07 +0000
commitfeb2aba5b692eb1c9cb8275d405791736ea1067e (patch)
tree4d1748985bcd82a072eb1a920c2920cda339e7cd /sys
parentdbef1afd93ab22bb7408d3258ee59494af7dc2ac (diff)
downloadFreeBSD-src-feb2aba5b692eb1c9cb8275d405791736ea1067e.zip
FreeBSD-src-feb2aba5b692eb1c9cb8275d405791736ea1067e.tar.gz
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
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/imgact_elf.c46
-rw-r--r--sys/kern/init_main.c3
-rw-r--r--sys/kern/kern_exec.c1
-rw-r--r--sys/kern/kern_mib.c1
-rw-r--r--sys/sys/proc.h2
-rw-r--r--sys/sys/systm.h1
6 files changed, 49 insertions, 5 deletions
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;
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index b536215..ed76ff8 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -373,9 +373,10 @@ proc0_init(void *dummy __unused)
td = &thread0;
/*
- * Initialize magic number.
+ * Initialize magic number and osrel.
*/
p->p_magic = P_MAGIC;
+ p->p_osrel = osreldate;
/*
* Initialize thread and process structures.
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index ddeac60..2878b37 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -391,6 +391,7 @@ interpret:
if (error)
goto exec_fail_dealloc;
+ imgp->proc->p_osrel = 0;
/*
* If the current process has a special image activator it
* wants to try first, call it. For example, emulating shell
diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c
index 52f8754..c405adf 100644
--- a/sys/kern/kern_mib.c
+++ b/sys/kern/kern_mib.c
@@ -104,7 +104,6 @@ SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD,
* NOTICE: The *userland* release date is available in
* /usr/include/osreldate.h
*/
-extern int osreldate;
SYSCTL_INT(_kern, KERN_OSRELDATE, osreldate, CTLFLAG_RD,
&osreldate, 0, "Kernel release date");
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index eaf6f03..7d0aca4 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -561,6 +561,8 @@ struct proc {
/* The following fields are all copied upon creation in fork. */
#define p_startcopy p_endzero
u_int p_magic; /* (b) Magic number. */
+ int p_osrel; /* (x) osreldate for the
+ binary (from ELF note, if any) */
char p_comm[MAXCOMLEN + 1]; /* (b) Process name. */
struct pgrp *p_pgrp; /* (c + e) Pointer to process group. */
struct sysentvec *p_sysent; /* (b) Syscall dispatch info. */
diff --git a/sys/sys/systm.h b/sys/sys/systm.h
index 21059ba..6809696 100644
--- a/sys/sys/systm.h
+++ b/sys/sys/systm.h
@@ -101,6 +101,7 @@ extern int maxusers; /* system tune hint */
* in two files.
* XXX most of these variables should be const.
*/
+extern int osreldate;
extern int envmode;
extern int hintmode; /* 0 = off. 1 = config, 2 = fallback */
extern int dynamic_kenv;
OpenPOWER on IntegriCloud