
/* Support for dynamic loading of extension modules */

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

#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 char *_PyImport_DynLoadFiletab[] = {".so", NULL};

static int
aix_getoldmodules(void **modlistptr)
{
    ModulePtr       modptr, prevmodptr;
    struct ld_info  *ldiptr;
    char            *ldibuf;
    int             errflag, bufsize = 1024;
    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;
    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 (Py_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_FindSharedFuncptr(const char *prefix,
                                       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;
}
