Re: crash of 32-bit powerpc -r347549 kernel built via system-clang-8, _init_tls is where the initial DIAGNOSTICS-reported SIGSEGV happens

Mark Millard via freebsd-hackers <[email protected]>
Newsgroups gmane.os.freebsd.devel.hackers,gmane.os.freebsd.devel.ppc
Message-ID <[email protected]>
So far I've not been able to find the code that is supposed
to establish the value of environ in /sbin/init as matching
the value of arginfo->ps_envstr from the exec_copyout_strings
use by do_execve in the kernel.

Anyone know where to point me to for what I seem to have
missed?

The issue driving the question is having the *sp++ in
_init_tls code below get SIGSEGV on 32-bit FreeBSD when
built via system-clang-8 and devel/powerpc64-binutils:

       sp = (Elf_Addr *) environ;
       while (*sp++ != 0)
               ;


The below is relevant detail that I've found.

_start in /sbin/init 's instance of lib/csu/powerpc/crt1.c
calls _init_tls that is from lib/libc/gen/tls.c but first
might assign to environ :

. . .
#include "ignore_init.c"
. . .
void
_start(int argc, char **argv, char **env,
    const struct Struct_Obj_Entry *obj __unused, void (*cleanup)(void),
    struct ps_strings *ps_strings)
{


        handle_argv(argc, argv, env);

        if (ps_strings != (struct ps_strings *)0)
                __ps_strings = ps_strings;

        if (&_DYNAMIC != NULL)
                atexit(cleanup);
        else
                _init_tls();

#ifdef GCRT
        atexit(_mcleanup);
        monstartup(&eprol, &etext);
#endif

        handle_static_init(argc, argv, env);
        exit(main(argc, argv, env));
}

lib/csu/common/ignore_init.c has:

char **environ;
. . .
static inline void
handle_argv(int argc, char *argv[], char **env)
{
        const char *s;

        if (environ == NULL)
                environ = env;
        if (argc > 0 && argv[0] != NULL) {
                __progname = argv[0];
                for (s = __progname; *s != '\0'; s++) {
                        if (*s == '/')
                                __progname = s + 1;
                }
        }
}

So _start's char**env argument might be used to assign
environ. But either way I've not managed to find the
binding to the kernel exec_copyout_strings operation.

_init_tls has the *sp++ loop that I referenced earlier:

extern char **environ;

void
_init_tls(void)
{
#ifndef PIC
       Elf_Addr *sp;
       Elf_Auxinfo *aux, *auxp;
       Elf_Phdr *phdr;
       size_t phent, phnum;
       int i;
       void *tls;

       sp = (Elf_Addr *) environ;
       while (*sp++ != 0)
               ;
. . .


On the kernel side for invoking /sbin/init is . . .

From /usr/src/sys/sys/imgact.h :

struct image_args {
        char *buf;              /* pointer to string buffer */
        void *bufkva;           /* cookie for string buffer KVA */
        char *begin_argv;       /* beginning of argv in buf */
        char *begin_envv;       /* (interal use only) beginning of envv in buf,
                                 * access with exec_args_get_begin_envv(). */
        char *endp;             /* current `end' pointer of arg & env strings */
        char *fname;            /* pointer to filename of executable (system space) */
        char *fname_buf;        /* pointer to optional malloc(M_TEMP) buffer */
        int stringspace;        /* space left in arg & env buffer */
        int argc;               /* count of argument strings */
        int envc;               /* count of environment strings */
        int fd;                 /* file descriptor of the executable */
        struct filedesc *fdp;   /* new file descriptor table */
};

do_execve from sys/kern/kern_exec.c has use, including envc
but avoiding begin_envv (via starting from begin_argv):

static int
do_execve(struct thread *td, struct image_args *args, struct mac *mac_p)
{
. . .
        /*
         * Copy out strings (args and env) and initialize stack base.
         */
        stack_base = (*p->p_sysent->sv_copyout_strings)(imgp);
                

The exec_copyout_strings code (accessed via ->sv_copyout_strings)
does

        stack_base = (register_t *)vectp;
                
        stringp = imgp->args->begin_argv;
        argc = imgp->args->argc;
        envc = imgp->args->envc;
. . .

        /* a null vector table pointer separates the argp's from the envp's */
        suword(vectp++, 0);

        suword(&arginfo->ps_envstr, (long)(intptr_t)vectp);
        suword32(&arginfo->ps_nenvstr, envc);

        /*
         * Fill in environment portion of vector table.
         */
        for (; envc > 0; --envc) {
                suword(vectp++, (long)(intptr_t)destp);
                while (*stringp++ != 0)
                        destp++;
                destp++;
        }

        /* end of vector table is a null pointer */
        suword(vectp, 0);
. . .

(From what I've seen for /sbin/init being invoked, envc==0 .)

The use involves struct ps_strings from /usr/src/sys/sys/exec.h :

struct ps_strings {
        char    **ps_argvstr;   /* first of 0 or more argument strings */
        unsigned int ps_nargvstr; /* the number of argument strings */
        char    **ps_envstr;    /* first of 0 or more environment strings */
        unsigned int ps_nenvstr; /* the number of environment strings */
};


The initialization of the begin_envv and envc for much of
the code seems to trace back to:

static void
start_init(void *dummy)
{
        struct image_args args;
. . .
        while ((path = strsep(&tmp_init_path, ":")) != NULL) {
                if (bootverbose)
                        printf("start_init: trying %s\n", path);

                memset(&args, 0, sizeof(args));
. . .


===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)

_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
To unsubscribe, send any mail to "[email protected]"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.