if (sod.sod_library && will_see_later(name)) { if ((offset = (off_t)sod.sod_next) == 0) break; else continue; }  subentry = (struct file_entry *) xmalloc(sizeof(struct file_entry)); bzero(subentry, sizeof(struct file_entry)); subentry->superfile = entry; subentry->flags = E_SECONDCLASS;
read_shared_object(fd, entry)	struct file_entry *entry;	int fd;{	struct _dynamic			dyn;	struct section_dispatch_table	sdt;	struct nlist			*np;	struct nzlist			*nzp;	int				n, i, has_nz = 0;	if (!(entry->flags & E_HEADER_VALID))		read_header(fd, entry);	/* Read DYNAMIC structure (first in data segment) */	if (lseek(fd, text_offset(entry) + entry->header.a_text, L_SET) ==	    (off_t)-1)		err(1, "%s: lseek", get_file_name(entry));	if (read(fd, &dyn, sizeof dyn) != sizeof dyn) {		errx(1, "%s: premature EOF reading _dynamic",			get_file_name(entry));	}	md_swapin__dynamic(&dyn);	/* Check version */	switch (dyn.d_version) {	default:		errx(1, "%s: unsupported _DYNAMIC version: %d",			get_file_name(entry), dyn.d_version);		break;	case LD_VERSION_SUN:		break;	case LD_VERSION_BSD:		has_nz = 1;		break;	}	/* Read Section Dispatch Table (from data segment) */	if (lseek(fd,	    text_offset(entry) + (long)dyn.d_un.d_sdt -		(DATA_START(entry->header) - N_DATOFF(entry->header)),	    L_SET) == (off_t)-1)		err(1, "%s: lseek", get_file_name(entry));	if (read(fd, &sdt, sizeof sdt) != sizeof sdt)		errx(1, "%s: premature EOF reading sdt",			get_file_name(entry));	md_swapin_section_dispatch_table(&sdt);	/* Read symbols (text segment) */	n = sdt.sdt_strings - sdt.sdt_nzlist;	entry->nsymbols = n /		(has_nz ? sizeof(struct nzlist) : sizeof(struct nlist));	nzp = (struct nzlist *)(np = (struct nlist *)alloca (n));	entry->symbols = (struct localsymbol *)		xmalloc(entry->nsymbols * sizeof(struct localsymbol));	if (lseek(fd,	    text_offset(entry) + (long)sdt.sdt_nzlist -		(TEXT_START(entry->header) - N_TXTOFF(entry->header)),	    L_SET) == (off_t)-1)		err(1, "%s: lseek", get_file_name(entry));	if (read(fd, (char *)nzp, n) != n)		errx(1, "%s: premature EOF reading symbols ",			get_file_name(entry));	if (has_nz)		md_swapin_zsymbols(nzp, entry->nsymbols);	else		md_swapin_symbols(np, entry->nsymbols);	/* Convert to structs localsymbol */	for (i = 0; i < entry->nsymbols; i++) {		if (has_nz) {			entry->symbols[i].nzlist = *nzp++;		} else {			entry->symbols[i].nzlist.nlist = *np++;			entry->symbols[i].nzlist.nz_size = 0;		}		entry->symbols[i].symbol = NULL;		entry->symbols[i].next = NULL;		entry->symbols[i].entry = entry;		entry->symbols[i].gotslot_offset = -1;		entry->symbols[i].flags = 0;	}	/* Read strings (text segment) */	n = entry->string_size = sdt.sdt_str_sz;	entry->strings = (char *)alloca(n);	entry->strings_offset = text_offset(entry) + sdt.sdt_strings;	if (lseek(fd,	    entry->strings_offset -		(TEXT_START(entry->header) - N_TXTOFF(entry->header)),	    L_SET) == (off_t)-1)		err(1, "%s: lseek", get_file_name(entry));	if (read(fd, entry->strings, n) != n)		errx(1, "%s: premature EOF reading strings",			get_file_name(entry));	enter_file_symbols (entry);	entry->strings = 0;	/*	 * Load any subsidiary shared objects.	 */	if (sdt.sdt_sods) {		struct sod		sod;		off_t			offset;		struct file_entry	*prev = NULL;		offset = (off_t)sdt.sdt_sods;		while (1) {			struct file_entry *subentry;			char *libname, name[MAXPATHLEN]; /*XXX*/			subentry = (struct file_entry *)				xmalloc(sizeof(struct file_entry));			bzero(subentry, sizeof(struct file_entry));			subentry->superfile = entry;			subentry->flags = E_SECONDCLASS;			if (lseek(fd,			    offset - (TEXT_START(entry->header) -				      N_TXTOFF(entry->header)),			    L_SET) == (off_t)-1)				err(1, "%s: lseek", get_file_name(entry));			if (read(fd, &sod, sizeof(sod)) != sizeof(sod))				errx(1, "%s: premature EOF reding sod",					get_file_name(entry));			md_swapin_sod(&sod, 1);			if (lseek(fd,			    (off_t)sod.sod_name - (TEXT_START(entry->header) -						   N_TXTOFF(entry->header)),			    L_SET) == (off_t)-1)				err(1, "%s: lseek", get_file_name(entry));			(void)read(fd, name, sizeof(name)); /*XXX*/			if (sod.sod_library) {				int sod_major = sod.sod_major;				int sod_minor = sod.sod_minor;				libname = findshlib(name,						&sod_major, &sod_minor, 0);				if (libname == NULL)					errx(1,"no shared -l%s.%d.%d available",					name, sod.sod_major, sod.sod_minor);				subentry->filename = libname;				subentry->local_sym_name = concat("-l", name, "");			} else {				subentry->filename = strdup(name);				subentry->local_sym_name = strdup(name);			}			/* Sanity check */			if (strcmp(subentry->filename, 			    subentry->superfile->filename) == 0)				errx(1, "loop in library dependencies: %s",				    subentry->filename);			read_file_symbols(subentry);			if (prev)				prev->chain = subentry;			else				entry->subfiles = subentry;			prev = subentry;			fd = file_open(entry);			if ((offset = (off_t)sod.sod_next) == 0)				break;		}	}#ifdef SUN_COMPAT	if (link_mode & SILLYARCHIVE) {		char			*cp, *sa_name;		char			armag[SARMAG];		int			fd;		struct file_entry	*subentry;		sa_name = strdup(entry->filename);		if (sa_name == NULL)			goto out;		cp = sa_name + strlen(sa_name) - 1;		while (cp > sa_name) {			if (!isdigit(*cp) && *cp != '.')				break;			--cp;		}		if (cp <= sa_name || *cp != 'o') {			/* Not in `libxxx.so.n.m' form */			free(sa_name);			goto out;		}		*cp = 'a';		if ((fd = open(sa_name, O_RDONLY, 0)) < 0)			goto out;		/* Read archive magic */		bzero(armag, SARMAG);		(void)read(fd, armag, SARMAG);		(void)close(fd);		if (strncmp(armag, ARMAG, SARMAG) != 0) {			warnx("%s: malformed silly archive",					get_file_name(entry));			goto out;		}		subentry = (struct file_entry *)				xmalloc(sizeof(struct file_entry));		bzero(subentry, sizeof(struct file_entry));		entry->silly_archive = subentry;		subentry->superfile = entry;		subentry->filename = sa_name;		subentry->local_sym_name = sa_name;		subentry->flags |= E_IS_LIBRARY;		search_library(file_open(subentry), subentry);out:		;	}#endif}