⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dso.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * to call global constructors using the _GLOBAL__DI function,	 * and later, global destructors using the _GLOBAL_DD	 * funciton.  --jwe	 */    }    else if (mp->gcc_ctor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DI")) {	(*mp->gcc_ctor) ();	mp->gcc_dtor = (GccCDtorPtr) dlsym(mp, "_GLOBAL__DD");    }    else	errvalid = 0;    return mp;}/* * Attempt to decipher an AIX loader error message and append it * to our static error message buffer. */static void caterr(char *s){    register char *p = s;    while (*p >= '0' && *p <= '9')	p++;    switch (atoi(s)) {    case L_ERROR_TOOMANY:	strcat(errbuf, "to many errors");	break;    case L_ERROR_NOLIB:	strcat(errbuf, "can't load library");	strcat(errbuf, p);	break;    case L_ERROR_UNDEF:	strcat(errbuf, "can't find symbol");	strcat(errbuf, p);	break;    case L_ERROR_RLDBAD:	strcat(errbuf, "bad RLD");	strcat(errbuf, p);	break;    case L_ERROR_FORMAT:	strcat(errbuf, "bad exec format in");	strcat(errbuf, p);	break;    case L_ERROR_ERRNO:	strcat(errbuf, strerror(atoi(++p)));	break;    default:	strcat(errbuf, s);	break;    }}void *dlsym(void *handle, const char *symbol){    register ModulePtr mp = (ModulePtr) handle;    register ExportPtr ep;    register int i;    /*     * Could speed up the search, but I assume that one assigns     * the result to function pointers anyways.     */    for (ep = mp->exports, i = mp->nExports; i; i--, ep++)	if (strcmp(ep->name, symbol) == 0)	    return ep->addr;    errvalid++;    strcpy(errbuf, "dlsym: undefined symbol ");    strcat(errbuf, symbol);    return NULL;}const char *dlerror(void){    if (errvalid) {	errvalid = 0;	return errbuf;    }    return NULL;}int dlclose(void *handle){    register ModulePtr mp = (ModulePtr) handle;    int result;    register ModulePtr mp1;    if (--mp->refCnt > 0)	return 0;    if (mp->info && mp->info->fini)	(*mp->info->fini) ();    if (mp->cdtors) {	CdtorPtr cp = mp->cdtors;	while (cp->init || cp->term) {	    if (cp->term && cp->init != (void (*)(void)) 0xffffffff)		(*cp->term) ();	    cp++;	}	/*	 * If the function to handle global destructors for g++	 * exists, call it.  --jwe	 */    }    else if (mp->gcc_dtor) {	(*mp->gcc_dtor) ();    }    result = unload(mp->entry);    if (result == -1) {	errvalid++;	strcpy(errbuf, strerror(errno));    }    if (mp->exports) {	register ExportPtr ep;	register int i;	for (ep = mp->exports, i = mp->nExports; i; i--, ep++)	    if (ep->name)		free(ep->name);	free(mp->exports);    }    if (mp == modList)	modList = mp->next;    else {	for (mp1 = modList; mp1; mp1 = mp1->next)	    if (mp1->next == mp) {		mp1->next = mp->next;		break;	    }    }    free(mp->name);    free(mp);    return result;}static void terminate(void){    while (modList)	dlclose(modList);}/* * Build the export table from the XCOFF .loader section. */static int readExports(ModulePtr mp){    LDFILE *ldp = NULL;    SCNHDR sh, shdata;    LDHDR *lhp;    char *ldbuf;    LDSYM *ls;    int i;    ExportPtr ep;    struct ld_info *lp;    char *buf;    int size = 4 * 1024;    void *dataorg;    /*     * The module might be loaded due to the LIBPATH     * environment variable. Search for the loaded     * module using L_GETINFO.     */    if ((buf = malloc(size)) == NULL) {	errvalid++;	strcpy(errbuf, "readExports: ");	strcat(errbuf, strerror(errno));	return -1;    }    while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {	free(buf);	size += 4 * 1024;	if ((buf = malloc(size)) == NULL) {	    errvalid++;	    strcpy(errbuf, "readExports: ");	    strcat(errbuf, strerror(errno));	    return -1;	}    }    if (i == -1) {	errvalid++;	strcpy(errbuf, "readExports: ");	strcat(errbuf, strerror(errno));	free(buf);	return -1;    }    /*     * Traverse the list of loaded modules. The entry point     * returned by load() does actually point to the TOC     * entry contained in the data segment.     */    lp = (struct ld_info *) buf;    while (lp) {	if ((unsigned long) mp->entry >= (unsigned long) lp->ldinfo_dataorg &&	    (unsigned long) mp->entry < (unsigned long) lp->ldinfo_dataorg +	    lp->ldinfo_datasize) {	    dataorg = lp->ldinfo_dataorg;	    ldp = ldopen(lp->ldinfo_filename, ldp);	    break;	}	if (lp->ldinfo_next == 0)	    lp = NULL;	else	    lp = (struct ld_info *) ((char *) lp + lp->ldinfo_next);    }    free(buf);    if (!ldp) {	errvalid++;	strcpy(errbuf, "readExports: ");	strcat(errbuf, strerror(errno));	return -1;    }    if (TYPE(ldp) != U802TOCMAGIC) {	errvalid++;	strcpy(errbuf, "readExports: bad magic");	while (ldclose(ldp) == FAILURE);	return -1;    }    /*     * Get the padding for the data section. This is needed for     * AIX 4.1 compilers. This is used when building the final     * function pointer to the exported symbol.     */    if (ldnshread(ldp, _DATA, &shdata) != SUCCESS) {	errvalid++;	strcpy(errbuf, "readExports: cannot read data section header");	while (ldclose(ldp) == FAILURE);	return -1;    }    if (ldnshread(ldp, _LOADER, &sh) != SUCCESS) {	errvalid++;	strcpy(errbuf, "readExports: cannot read loader section header");	while (ldclose(ldp) == FAILURE);	return -1;    }    /*     * We read the complete loader section in one chunk, this makes     * finding long symbol names residing in the string table easier.     */    if ((ldbuf = (char *) malloc(sh.s_size)) == NULL) {	errvalid++;	strcpy(errbuf, "readExports: ");	strcat(errbuf, strerror(errno));	while (ldclose(ldp) == FAILURE);	return -1;    }    if (FSEEK(ldp, sh.s_scnptr, BEGINNING) != OKFSEEK) {	errvalid++;	strcpy(errbuf, "readExports: cannot seek to loader section");	free(ldbuf);	while (ldclose(ldp) == FAILURE);	return -1;    }    if (FREAD(ldbuf, sh.s_size, 1, ldp) != 1) {	errvalid++;	strcpy(errbuf, "readExports: cannot read loader section");	free(ldbuf);	while (ldclose(ldp) == FAILURE);	return -1;    }    lhp = (LDHDR *) ldbuf;    ls = (LDSYM *) (ldbuf + LDHDRSZ);    /*     * Count the number of exports to include in our export table.     */    for (i = lhp->l_nsyms; i; i--, ls++) {	if (!LDR_EXPORT(*ls))	    continue;	mp->nExports++;    }    if ((mp->exports = (ExportPtr) calloc(mp->nExports, sizeof(*mp->exports))) == NULL) {	errvalid++;	strcpy(errbuf, "readExports: ");	strcat(errbuf, strerror(errno));	free(ldbuf);	while (ldclose(ldp) == FAILURE);	return -1;    }    /*     * Fill in the export table. All entries are relative to     * the beginning of the data origin.     */    ep = mp->exports;    ls = (LDSYM *) (ldbuf + LDHDRSZ);    for (i = lhp->l_nsyms; i; i--, ls++) {	char *symname;	char tmpsym[SYMNMLEN + 1];	if (!LDR_EXPORT(*ls))	    continue;	if (ls->l_zeroes == 0)	    symname = ls->l_offset + lhp->l_stoff + ldbuf;	else {	    /*	     * The l_name member is not zero terminated, we	     * must copy the first SYMNMLEN chars and make	     * sure we have a zero byte at the end.	     */	    strncpy(tmpsym, ls->l_name, SYMNMLEN);	    tmpsym[SYMNMLEN] = '\0';	    symname = tmpsym;	}	ep->name = strdup(symname);	ep->addr = (void *) ((unsigned long) dataorg +			     ls->l_value - shdata.s_vaddr);	ep++;    }    free(ldbuf);    while (ldclose(ldp) == FAILURE);    return 0;}/* * Find the main modules data origin. This is used as export pointer * for loadbind() to be able to resolve references to the main part. */static void *findMain(void){    struct ld_info *lp;    char *buf;    int size = 4 * 1024;    int i;    void *ret;    if ((buf = malloc(size)) == NULL) {	errvalid++;	strcpy(errbuf, "findMain: ");	strcat(errbuf, strerror(errno));	return NULL;    }    while ((i = loadquery(L_GETINFO, buf, size)) == -1 && errno == ENOMEM) {	free(buf);	size += 4 * 1024;	if ((buf = malloc(size)) == NULL) {	    errvalid++;	    strcpy(errbuf, "findMain: ");	    strcat(errbuf, strerror(errno));	    return NULL;	}    }    if (i == -1) {	errvalid++;	strcpy(errbuf, "findMain: ");	strcat(errbuf, strerror(errno));	free(buf);	return NULL;    }    /*     * The first entry is the main module. The data segment     * starts with the TOC entries for all exports, so the     * data segment origin works as argument for loadbind.     */    lp = (struct ld_info *) buf;    ret = lp->ldinfo_dataorg;    free(buf);    return ret;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -