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:
parent
93d1c72883
commit
f231de478e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=174253
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user