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
This commit is contained in:
Konstantin Belousov 2007-12-04 12:28:07 +00:00
parent 93d1c72883
commit f231de478e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=174253
6 changed files with 49 additions and 5 deletions

View File

@ -597,11 +597,13 @@ __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
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;

View File

@ -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.

View File

@ -391,6 +391,7 @@ do_execve(td, args, mac_p)
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

View File

@ -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");

View File

@ -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. */

View File

@ -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;