FreeBSD: Fix auxv AT_EXECPATH

This was being copied from the host. Now it's synthesized for
the guest. Also improve the none/freebsd/auxv test to
print a few of the strings in auxv (but not the envp ones).
This commit is contained in:
Paul Floyd 2023-01-21 20:46:24 +01:00
parent 2b1c6db9c8
commit a526bbd051
12 changed files with 90 additions and 37 deletions

View File

@ -410,6 +410,10 @@ Addr setup_client_stack( void* init_sp,
vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
vg_assert( VG_(args_for_client) );
const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename));
HChar resolved_name[VKI_PATH_MAX];
VG_(realpath)(exe_name, resolved_name);
/* use our own auxv as a prototype */
orig_auxv = find_auxv(init_sp);
@ -459,8 +463,7 @@ Addr setup_client_stack( void* init_sp,
auxsize += sizeof(*cauxv);
switch(cauxv->a_type) {
case VKI_AT_EXECPATH:
// @todo PJF this is wrong this will be the name of the execed tool
stringsize += VG_(strlen)(cauxv->u.a_ptr) + 1;
stringsize += VG_(strlen)(resolved_name) + 1;
break;
case VKI_AT_CANARYLEN:
canarylen = cauxv->u.a_val;
@ -686,8 +689,7 @@ Addr setup_client_stack( void* init_sp,
break;
case VKI_AT_EXECPATH:
// @todo PJF this is wrong this will be the name of the execed tool
auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr);
auxv->u.a_ptr = copy_str(&strtab, resolved_name);
break;
case VKI_AT_CANARY:
if (canarylen >= 1) {

View File

@ -1761,7 +1761,6 @@ const HChar *VG_(dirname)(const HChar *path)
}
#if defined(VGO_freebsd)
#if (FREEBSD_VERS >= FREEBSD_13_0)
/*
* I did look at nicking this from FreeBSD, it's fairly easy to port
* but I was put off by the copyright and 3-clause licence
@ -1777,9 +1776,38 @@ Bool VG_(realpath)(const HChar *path, HChar *resolved)
{
vg_assert(path);
vg_assert(resolved);
#if (FREEBSD_VERS >= FREEBSD_13_0)
return !sr_isError(VG_(do_syscall5)(__NR___realpathat, VKI_AT_FDCWD, (RegWord)path, (RegWord)resolved, VKI_PATH_MAX, 0));
}
#else
// poor man's realpath
const HChar *resolved_name;
HChar tmp[VKI_PATH_MAX];
struct vg_stat statbuf;
SysRes res = VG_(lstat)(exe_name, &statbuf);
if (sr_isError(res)) {
return False;
} else if (VKI_S_ISLNK(statbuf.mode)) {
SizeT link_len = VG_(readlink)(exe_name, tmp, VKI_PATH_MAX);
tmp[link_len] = '\0';
resolved_name = tmp;
} else {
// not a link
resolved_name = exe_name;
}
if (resolved_name[0] != '/') {
// relative path
if (resolved_name[0] == '.' && resolved_name[1] == '/') {
resolved_name += 2;
}
VG_(snprintf)(out, *len, "%s/%s", VG_(get_startup_wd)(), resolved_name);
} else {
VG_(snprintf)(out, *len, "%s", resolved_name);
}
#endif
}
#endif

View File

@ -1944,39 +1944,12 @@ static Bool sysctl_kern_proc_pathname(HChar *out, SizeT *len)
// is this stashed somewhere?
const HChar *exe_name = VG_(find_executable)(VG_(args_the_exename));
#if (FREEBSD_VERS >= FREEBSD_13_0)
return VG_(realpath)(exe_name, out);
#else
// poor man's realpath
const HChar *resolved_name;
HChar tmp[VKI_PATH_MAX];
struct vg_stat statbuf;
SysRes res = VG_(lstat)(exe_name, &statbuf);
if (sr_isError(res)) {
if (!VG_(realpath)(exe_name, out)) {
return False;
} else if (VKI_S_ISLNK(statbuf.mode)) {
SizeT link_len = VG_(readlink)(exe_name, tmp, VKI_PATH_MAX);
tmp[link_len] = '\0';
resolved_name = tmp;
} else {
// not a link
resolved_name = exe_name;
}
if (resolved_name[0] != '/') {
// relative path
if (resolved_name[0] == '.' && resolved_name[1] == '/') {
resolved_name += 2;
}
VG_(snprintf)(out, *len, "%s/%s", VG_(get_startup_wd)(), resolved_name);
} else {
VG_(snprintf)(out, *len, "%s", resolved_name);
}
*len = VG_(strlen)(out)+1;
return True;
#endif
}
// SYS___sysctl 202

View File

@ -111,10 +111,8 @@ extern Int VG_(mkstemp) ( const HChar* part_of_name, /*OUT*/HChar* fullname );
extern void VG_(record_startup_wd) ( void );
#if defined(VGO_freebsd)
#if (FREEBSD_VERS >= FREEBSD_13_0)
extern Bool VG_(realpath)(const HChar *path, HChar *resolved);
#endif
#endif
#endif // __PUB_CORE_LIBCFILE_H

View File

@ -1,7 +1,8 @@
include $(top_srcdir)/Makefile.tool-tests.am
dist_noinst_SCRIPTS = filter_stderr test.sh filter_452275
dist_noinst_SCRIPTS = filter_stderr test.sh filter_452275 filter_auxv
EXTRA_DIST = \
auxv.vgtest \
auxv.stderr.exp \

View File

@ -1,5 +1,6 @@
#include <stdio.h>
#include <elf.h>
#include <sys/exec.h>
#include "../../../config.h"
/* /usr/include/x86/elf.h AT_* defs */
@ -71,5 +72,38 @@ int main(int argc, char* argv[], char* envp[])
{
aux_str = &aux_map[auxp->a_type];
fprintf(stderr, "val: %s int: %02d ptr: 0x%lx\n", aux_str->str_val, aux_str->type, auxp->a_un.a_val);
switch ( aux_str->type)
{
case AT_EXECPATH:
if (auxp->a_un.a_val != 0)
{
fprintf(stderr, "EXECPATH: %s\n", (char*)auxp->a_un.a_val);
}
break;
case AT_ARGV:
if (auxp->a_un.a_val != 0)
{
fprintf(stderr, "ARGV: %s\n", *(char**)auxp->a_un.a_val);
}
break;
case AT_ENVV:
if (auxp->a_un.a_val != 0)
{
/* can't leave this in regtest don't know what it
* will be */
/*fprintf(stderr, "ENVV: %s\n", *(char**)auxp->a_un.a_val);*/
}
break;
case AT_PS_STRINGS:
if (auxp->a_un.a_val != 0)
{
struct ps_strings *ppss = (struct ps_strings*)auxp->a_un.a_val;
fprintf(stderr, "PS_STRINGS ARGV: %s\n", *ppss->ps_argvstr);
/* can't leave this in regtest don't know what it
* will be */
/*fprintf(stderr, "PS_STRINGS ENVV: %s\n", *ppss->ps_envstr);*/
}
break;
}
}
}

View File

@ -7,6 +7,7 @@ val: AT_ENTRY int: 09 ptr: 0x........
val: AT_BASE int: 07 ptr: 0x........
val: AT_EHDRFLAGS int: 24 ptr: 0x........
val: AT_EXECPATH int: 15 ptr: 0x........
EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv
val: AT_OSRELDATE int: 18 ptr: 0x........
val: AT_CANARY int: 16 ptr: 0x........
val: AT_CANARYLEN int: 17 ptr: 0x........

View File

@ -7,6 +7,7 @@ val: AT_ENTRY int: 09 ptr: 0x........
val: AT_BASE int: 07 ptr: 0x........
val: AT_EHDRFLAGS int: 24 ptr: 0x........
val: AT_EXECPATH int: 15 ptr: 0x........
EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv
val: AT_OSRELDATE int: 18 ptr: 0x........
val: AT_CANARY int: 16 ptr: 0x........
val: AT_CANARYLEN int: 17 ptr: 0x........
@ -18,6 +19,8 @@ val: AT_STACKPROT int: 23 ptr: 0x........
val: AT_IGNORE int: 01 ptr: 0x........
val: AT_ARGC int: 28 ptr: 0x........
val: AT_ARGV int: 29 ptr: 0x........
ARGV: ./auxv
val: AT_ENVC int: 30 ptr: 0x........
val: AT_ENVV int: 31 ptr: 0x........
val: AT_PS_STRINGS int: 32 ptr: 0x........
PS_STRINGS ARGV: ./auxv

View File

@ -7,6 +7,7 @@ val: AT_ENTRY int: 09 ptr: 0x........
val: AT_BASE int: 07 ptr: 0x........
val: AT_EHDRFLAGS int: 24 ptr: 0x........
val: AT_EXECPATH int: 15 ptr: 0x........
EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv
val: AT_OSRELDATE int: 18 ptr: 0x........
val: AT_CANARY int: 16 ptr: 0x........
val: AT_CANARYLEN int: 17 ptr: 0x........
@ -18,7 +19,9 @@ val: AT_STACKPROT int: 23 ptr: 0x........
val: AT_IGNORE int: 01 ptr: 0x........
val: AT_ARGC int: 28 ptr: 0x........
val: AT_ARGV int: 29 ptr: 0x........
ARGV: ./auxv
val: AT_ENVC int: 30 ptr: 0x........
val: AT_ENVV int: 31 ptr: 0x........
val: AT_PS_STRINGS int: 32 ptr: 0x........
PS_STRINGS ARGV: ./auxv
val: AT_IGNORE int: 01 ptr: 0x........

View File

@ -7,6 +7,7 @@ val: AT_ENTRY int: 09 ptr: 0x........
val: AT_BASE int: 07 ptr: 0x........
val: AT_EHDRFLAGS int: 24 ptr: 0x........
val: AT_EXECPATH int: 15 ptr: 0x........
EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv
val: AT_OSRELDATE int: 18 ptr: 0x........
val: AT_CANARY int: 16 ptr: 0x........
val: AT_CANARYLEN int: 17 ptr: 0x........
@ -18,9 +19,11 @@ val: AT_STACKPROT int: 23 ptr: 0x........
val: AT_IGNORE int: 01 ptr: 0x........
val: AT_ARGC int: 28 ptr: 0x........
val: AT_ARGV int: 29 ptr: 0x........
ARGV: ./auxv
val: AT_ENVC int: 30 ptr: 0x........
val: AT_ENVV int: 31 ptr: 0x........
val: AT_PS_STRINGS int: 32 ptr: 0x........
PS_STRINGS ARGV: ./auxv
val: AT_IGNORE int: 01 ptr: 0x........
val: AT_USRSTACKBASE int: 35 ptr: 0x........
val: AT_USRSTACKLIM int: 36 ptr: 0x........

View File

@ -1,3 +1,4 @@
prog: auxv
vgopts: -q
stderr_filter: filter_auxv

6
none/tests/freebsd/filter_auxv Executable file
View File

@ -0,0 +1,6 @@
#! /bin/sh
./filter_stderr |
sed 's#EXECPATH: .*/valgrind/none/tests/freebsd/auxv#EXECPATH: BASEDIR/valgrind/none/tests/freebsd/auxv#'