
/* Support for dynamic loading of extension modules */

#include "Python.h"
#include "importdl.h"

#include <ctype.h>      /*  for isdigit()         */
#include <errno.h>      /*  for global errno      */
#include <string.h>     /*  for strerror()        */
#include <stdlib.h>     /*  for malloc(), free()  */
#include <sys/ldr.h>


#ifdef AIX_GENUINE_CPLUSPLUS
#include <load.h>
#define aix_load loadAndInit
#else
#define aix_load load
#endif


extern char *Py_GetProgramName(void);

typedef struct Module {
    struct Module *next;
    void          *entry;
} Module, *ModulePtr;

const struct filedescr _PyImport_DynLoadFiletab[] = {
    {".so", "rb", C_EXTENSION},
    {0, 0}
};

static int
aix_getoldmodules(void **modlistptr)
{
    register ModulePtr       modptr, prevmodptr;
    register struct ld_info  *ldiptr;
    register char            *ldibuf;
    register int             errflag, bufsize = 1024;
    register unsigned int    offset;
    char *progname = Py_GetProgramName();

    /*
    -- Get the list of loaded modules into ld_info structures.
    */
    if ((ldibuf = malloc(bufsize)) == NULL) {
        PyErr_SetString(PyExc_ImportError, strerror(errno));
        return -1;
    }
    while ((errflag = loadquery(L_GETINFO, ldibuf, bufsize)) == -1
           && errno == ENOMEM) {
        free(ldibuf);
        bufsize += 1024;
        if ((ldibuf = malloc(bufsize)) == NULL) {
            PyErr_SetString(PyExc_ImportError, strerror(errno));
            return -1;
        }
    }
    if (errflag == -1) {
        PyErr_SetString(PyExc_ImportError, strerror(errno));
        return -1;
    }
    /*
    -- Make the modules list from the ld_info structures.
    */
    ldiptr = (struct ld_info *)ldibuf;
    prevmodptr = NULL;
    do {
        if (strstr(progname, ldiptr->ldinfo_filename) == NULL &&
            strstr(ldiptr->ldinfo_filename, "python") == NULL) {
            /*
            -- Extract only the modules belonging to the main
            -- executable + those containing "python" as a
            -- substring (like the "python[version]" binary or
            -- "libpython[version].a" in case it's a shared lib).
            */
            offset = (unsigned int)ldiptr->ldinfo_next;
            ldiptr = (struct ld_info *)((char*)ldiptr + offset);
            continue;
        }
        if ((modptr = (ModulePtr)malloc(sizeof(Module))) == NULL) {
            PyErr_SetString(PyExc_ImportError, strerror(errno));
            while (*modlistptr) {
                modptr = (ModulePtr)*modlistptr;
                *modlistptr = (void *)modptr->next;
                free(modptr);
            }
            return -1;
        }
        modptr->entry = ldiptr->ldinfo_dataorg;
        modptr->next  = NULL;
        if (prevmodptr == NULL)
            *modlistptr = (void *)modptr;
        else
            prevmodptr->next = modptr;
        prevmodptr = modptr;
        offset = (unsigned int)ldiptr->ldinfo_next;
        ldiptr = (struct ld_info *)((char*)ldiptr + offset);
    } while (offset);
    free(ldibuf);
    return 0;
}


static void
aix_loaderror(const char *pathname)
{

    char *message[1024], errbuf[1024];
    PyObject *pathname_ob = NULL;
    PyObject *errbuf_ob = NULL;
    register int i,j;

    struct errtab {
        int errNo;
        char *errstr;
    } load_errtab[] = {
        {L_ERROR_TOOMANY,               "too many errors, rest skipped."},
        {L_ERROR_NOLIB,                 "can't load library:"},
        {L_ERROR_UNDEF,                 "can't find symbol in library:"},
        {L_ERROR_RLDBAD,
         "RLD index out of range or bad relocation type:"},
        {L_ERROR_FORMAT,                "not a valid, executable xcoff file:"},
        {L_ERROR_MEMBER,
         "file not an archive or does not contain requested member:"},
        {L_ERROR_TYPE,                  "symbol table mismatch:"},
        {L_ERROR_ALIGN,                 "text alignment in file is wrong."},
        {L_ERROR_SYSTEM,                "System error:"},
        {L_ERROR_ERRNO,                 NULL}
    };

#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)

    PyOS_snprintf(errbuf, sizeof(errbuf), "from module %.200s ", pathname);

    if (!loadquery(L_GETMESSAGES, &message[0], sizeof(message))) {
        ERRBUF_APPEND(strerror(errno));
        ERRBUF_APPEND("\n");
    }
    for(i = 0; message[i] && *message[i]; i++) {
        int nerr = atoi(message[i]);
        for (j=0; j < Py_ARRAY_LENGTH(load_errtab); j++) {
            if (nerr == load_errtab[j].errNo && load_errtab[j].errstr)
            ERRBUF_APPEND(load_errtab[j].errstr);
        }
        while (isdigit(Py_CHARMASK(*message[i]))) message[i]++ ;
        ERRBUF_APPEND(message[i]);
        ERRBUF_APPEND("\n");
    }
    errbuf[strlen(errbuf)-1] = '\0';            /* trim off last newline */
    pathname_ob = PyUnicode_FromString(pathname);
    errbuf_ob = PyUnicode_FromString(errbuf);
    PyErr_SetImportError(errbuf_ob, NULL, pathname);
    Py_DECREF(pathname_ob);
    Py_DECREF(errbuf_ob);
    return;
}


dl_funcptr _PyImport_GetDynLoadFunc(const char *shortname,
                                    const char *pathname, FILE *fp)
{
    dl_funcptr p;

    /*
    -- Invoke load() with L_NOAUTODEFER leaving the imported symbols
    -- of the shared module unresolved. Thus we have to resolve them
    -- explicitly with loadbind. The new module is loaded, then we
    -- resolve its symbols using the list of already loaded modules
    -- (only those that belong to the python executable). Get these
    -- with loadquery(L_GETINFO).
    */

    static void *staticmodlistptr = NULL;

    if (!staticmodlistptr)
        if (aix_getoldmodules(&staticmodlistptr) == -1)
            return NULL;
    p = (dl_funcptr) aix_load((char *)pathname, L_NOAUTODEFER, 0);
    if (p == NULL) {
        aix_loaderror(pathname);
        return NULL;
    }

    return p;
}
