コード例 #1
0
ファイル: cmpdylib.c プロジェクト: disigma/darwin-cctools
/*
 * process_old() is called once for each architecture in the old dynamic shared
 * library and then causes compare() to be called for the same architecture
 * in the new dynamic shared library.
 */
static
void
process_old(
struct ofile *old_ofile,
char *arch_name,
void *cookie)
{
    struct arch_flag arch_flag;

	/* check to make sure this is a dynamic shared library */
	check_dylib(old_ofile, arch_name);

	/* fill in the architecure info */
	arch_flag.name = (char *)get_arch_name_from_types(
						old_ofile->mh_cputype,
						old_ofile->mh_cpusubtype);
	arch_flag.cputype = old_ofile->mh_cputype;
	arch_flag.cpusubtype = old_ofile->mh_cpusubtype;

	arch_processed = FALSE;
	arch_name_being_processed = arch_name;

	ofile_process(new_dylib, &arch_flag, 1, FALSE, TRUE, TRUE, FALSE,
		      compare, old_ofile);

	if(arch_processed == FALSE)
	    fatal("new dynamic shared library: %s  does not contain "
		  "architecture %s\n", new_dylib, arch_flag.name);
}
コード例 #2
0
ファイル: cmpdylib.c プロジェクト: disigma/darwin-cctools
/*
 * compare() checks the new dynamic shared library against the old one for the
 * same architecture.  The old dynamic shared library's ofile struct is passed
 * as the cookie.
 */
static
void
compare(
struct ofile *new_ofile,
char *arch_name,
void *cookie)
{
    uint32_t i;
    struct load_command *lc;
    struct ofile *old_ofile;
    struct dylib_command *old_dl, *new_dl;
    char *old_install_name, *new_install_name;
    enum bool new_api_allowed;
    uint32_t ncmds;

	arch_name = arch_name_being_processed;

	/* check to make sure this is a dynamic shared library */
	check_dylib(new_ofile, arch_name);

	old_ofile = (struct ofile *)cookie;

	/* Get the LC_ID_DYLIB from the old dylib */
	old_dl = NULL;
	lc = old_ofile->load_commands;
	if(old_ofile->mh != NULL)
	    ncmds = old_ofile->mh->ncmds;
	else
	    ncmds = old_ofile->mh64->ncmds;
	for(i = 0; i < ncmds; i++){
	    if(old_dl == NULL && lc->cmd == LC_ID_DYLIB){
		old_dl = (struct dylib_command *)lc;
	    }
	    lc = (struct load_command *)((char *)lc + lc->cmdsize);
	}
	if(old_dl == NULL){
	    if(arch_name != NULL)
		fatal("malformed dynamic shared library: %s (for architecture "
		      "%s) (has no dylib id command)", old_dylib, arch_name);
	    else
		fatal("malformed dynamic shared library: %s (has no dylib id "
		      "command)", old_dylib);
	}
	old_install_name = (char *)old_dl + old_dl->dylib.name.offset;
	if(old_dl->dylib.current_version <
	   old_dl->dylib.compatibility_version){
	    if(arch_name != NULL)
		fatal("malformed dynamic shared library: %s (for architecture "
		      "%s) (current version less than compatibility_version)",
		      old_dylib, arch_name);
	    else
		fatal("malformed dynamic shared library: %s (current version "
		      "less than compatibility_version)", old_dylib);
	}

	/* Get the LC_ID_DYLIB from the new dylib */
	new_dl = NULL;
	lc = new_ofile->load_commands;
	if(new_ofile->mh != NULL)
	    ncmds = new_ofile->mh->ncmds;
	else
	    ncmds = new_ofile->mh64->ncmds;
	for(i = 0; i < ncmds; i++){
	    if(new_dl == NULL && lc->cmd == LC_ID_DYLIB){
		new_dl = (struct dylib_command *)lc;
	    }
	    lc = (struct load_command *)((char *)lc + lc->cmdsize);
	}
	if(new_dl == NULL){
	    if(arch_name != NULL)
		fatal("malformed dynamic shared library: %s (for architecture "
		      "%s) (has no dylib id command)", new_dylib, arch_name);
	    else
		fatal("malformed dynamic shared library: %s (has no dylib id "
		      "command)", new_dylib);
	}
	new_install_name = (char *)new_dl + new_dl->dylib.name.offset;
	if(new_dl->dylib.current_version <
	   new_dl->dylib.compatibility_version){
	    if(arch_name != NULL)
		fatal("malformed dynamic shared library: %s (for architecture "
		      "%s) (current version less than compatibility_version)",
		      new_dylib, arch_name);
	    else
		fatal("malformed dynamic shared library: %s (current version "
		      "less than compatibility_version)", new_dylib);
	}

	/* check the values of the LC_ID_DYLIB's */
	if(strcmp(old_install_name, new_install_name) != 0){
	    if(arch_name != NULL)
		printf("For architecture %s ", arch_name);
	    printf("dynamic shared libraries have different install names (%s "
		   "and %s)\n", old_install_name, new_install_name);
	    compatible = FALSE;
	}
	if(old_dl->dylib.current_version >
	   new_dl->dylib.current_version){
	    if(arch_name != NULL)
		printf("For architecture %s ", arch_name);
	    printf("current version of old dynamic shared library (%u) "
		   "greater than new dynamic shared library (%u)\n",
		   old_dl->dylib.current_version,new_dl->dylib.current_version);
	    compatible = FALSE;
	}
	if(old_dl->dylib.compatibility_version >
	   new_dl->dylib.compatibility_version){
	    if(arch_name != NULL)
		printf("For architecture %s ", arch_name);
	    printf("compatibility version of old dynamic shared library (%u) "
		   "greater than new dynamic shared library (%u)\n",
		   old_dl->dylib.compatibility_version,
		   new_dl->dylib.compatibility_version);
	    compatible = FALSE;
	    new_api_allowed = TRUE;
	}
	else{
	    if(new_dl->dylib.compatibility_version !=
	       old_dl->dylib.compatibility_version)
		new_api_allowed = TRUE;
	    else
		new_api_allowed = FALSE;
	}

	check_global_symbols(new_ofile, old_ofile, arch_name, new_api_allowed);

	arch_processed = TRUE;
}
コード例 #3
0
ファイル: checksyms.c プロジェクト: bihai/xchain
/*
 * checksyms() is the routine that gets called by ofile_process() to process
 * single object files.
 */
static
void
checksyms(
struct ofile *ofile,
char *arch_name,
void *cookie)
{
    struct cmd_flags *cmd_flags;
    unsigned long i;
    struct load_command *lc;
    struct symtab_command *st;
    struct nlist *symbols;
    unsigned long nsymbols;
    char *strings;
    unsigned long strsize;
    unsigned long nfiledefs, ncats, nlocal, nstabs, nfun;
    unsigned long filedef_strings, cat_strings, local_strings, stab_strings;
    enum bool debug;

	if(ofile->mh == NULL)
	    return;

	debug = FALSE;
	cmd_flags = (struct cmd_flags *)cookie;

	if(cmd_flags->check_dynamic_binary == TRUE)
	    if((ofile->mh->flags & MH_DYLDLINK) == MH_DYLDLINK)
		check_dynamic_binary(ofile, arch_name, cmd_flags->detail,
				     cmd_flags->verification);

	if(ofile->mh->filetype == MH_DYLIB ||
	   ofile->mh->filetype == MH_DYLIB_STUB)
	    check_dylib(ofile, arch_name, cmd_flags->detail,
			cmd_flags->verification, &debug);

	st = NULL;
	lc = ofile->load_commands;
	for(i = 0; i < ofile->mh->ncmds; i++){
	    if(st == NULL && lc->cmd == LC_SYMTAB){
		st = (struct symtab_command *)lc;
	    }
	    lc = (struct load_command *)((char *)lc + lc->cmdsize);
	}
	if(st == NULL || st->nsyms == 0){
	    return;
	}

	if(cmd_flags->rldtype == FALSE &&
	   cmd_flags->trey == FALSE &&
	   (ofile->mh->flags & MH_DYLDLINK) == 0 &&
	    (ofile->file_type != OFILE_FAT ||
	     ofile->arch_type != OFILE_ARCHIVE) &&
	    ofile->file_type != OFILE_ARCHIVE &&
	    ofile->mh->filetype != MH_FVMLIB){
	    if(st->nsyms == 0)
		return;

	    if(cmd_flags->detail == TRUE){
		if(arch_name != NULL)
		    printf("(for architecture %s):", arch_name);
		if(ofile->member_ar_hdr != NULL){
		    printf("%s:%.*s:", ofile->file_name,
			   (int)ofile->member_name_size, ofile->member_name);
		}
		else
		    printf("%s:", ofile->file_name);
		printf(" has %u symbols and %u string bytes\n", st->nsyms,
		       st->strsize);
	    }
	    if(cmd_flags->verification == TRUE)
		printf("unstripped_binary\n");
	    exit_status = EXIT_FAILURE;
	    return;
	}

	symbols = (struct nlist *)(ofile->object_addr + st->symoff);
	nsymbols = st->nsyms;
	if(ofile->object_byte_sex != get_host_byte_sex())
	    swap_nlist(symbols, nsymbols, get_host_byte_sex());

	strings = ofile->object_addr + st->stroff;
	strsize = st->strsize;
	for(i = 0; i < nsymbols; i++){
	    if(symbols[i].n_un.n_strx == 0)
		symbols[i].n_un.n_name = "";
	    else if(symbols[i].n_un.n_strx < 0 ||
		    (unsigned long)symbols[i].n_un.n_strx > st->strsize)
		symbols[i].n_un.n_name = "bad string index";
	    else
		symbols[i].n_un.n_name = symbols[i].n_un.n_strx + strings;

	    if((symbols[i].n_type & N_TYPE) == N_INDR){
		if(symbols[i].n_value == 0)
		    symbols[i].n_value = (long)"";
		else if(symbols[i].n_value > st->strsize)
		    symbols[i].n_value = (long)"bad string index";
		else
		    symbols[i].n_value =
				(long)(symbols[i].n_value + strings);
	    }
	}

	nfiledefs = 0;
	ncats = 0;
	nlocal = 0;
	nstabs = 0;
	nfun = 0;
	filedef_strings = 0;
	cat_strings = 0;
	local_strings = 0;
	stab_strings = 0;
	for(i = 0; i < nsymbols; i++){
	    if(ofile->mh->filetype == MH_EXECUTE){
		if(symbols[i].n_type == (N_ABS | N_EXT) &&
		   symbols[i].n_value == 0){
		    if(strncmp(symbols[i].n_un.n_name, ".file_definition_",
			       sizeof(".file_definition_") - 1) == 0){
			nfiledefs++;
			filedef_strings += strlen(symbols[i].n_un.n_name);
		    }
		    if(strncmp(symbols[i].n_un.n_name, ".objc_category_name_",
			       sizeof(".objc_category_name_") - 1) == 0){
			ncats++;
			cat_strings += strlen(symbols[i].n_un.n_name);
		    }
		}
	    }
	    if((symbols[i].n_type & N_EXT) == 0){
		nlocal++;
		local_strings += strlen(symbols[i].n_un.n_name);
	    }
	    if(symbols[i].n_type & N_STAB){
		nstabs++;
		stab_strings += strlen(symbols[i].n_un.n_name);
		if(symbols[i].n_type == N_FUN)
		    nfun++;
	    }
	}

	if(nfiledefs == 0 && ncats == 0 && nlocal == 0 && nstabs == 0)
	    return;
	if(cmd_flags->rldtype == TRUE && nstabs == 0)
	    return;
	if((ofile->mh->flags & MH_DYLDLINK) == MH_DYLDLINK &&
	   (nstabs == 0 && nlocal == 0))
	    return;
	if(nstabs == 0 &&
	   ((ofile->file_type == OFILE_FAT &&
	     ofile->arch_type == OFILE_ARCHIVE) ||
	    ofile->file_type == OFILE_ARCHIVE ||
	    ofile->mh->filetype == MH_FVMLIB))
	    return;
	if((ofile->mh->filetype == MH_DYLIB ||
	    ofile->mh->filetype == MH_DYLIB_STUB ||
	    ofile->mh->filetype == MH_FVMLIB) &&
	    (nfun == 0 || debug == TRUE))
	    return;

	if(cmd_flags->detail == TRUE){
	    if(arch_name != NULL)
		printf("(for architecture %s):", arch_name);
	    if(ofile->member_ar_hdr != NULL){
		printf("%s:%.*s:", ofile->file_name,
		       (int)ofile->member_name_size, ofile->member_name);
	    }
	    else
		printf("%s:", ofile->file_name);
	    printf("\n");
	    if(nfiledefs != 0)
		printf(" has %lu .file_definition_ symbols and %lu string "
		       "bytes\n", nfiledefs, filedef_strings);
	    if(ncats != 0)
		printf(" has %lu .objc_category_name_ symbols and %lu string "
		       "bytes\n", ncats, cat_strings);
	    if(nlocal != 0)
		printf(" has %lu local symbols and %lu string "
		       "bytes\n", nlocal, local_strings);
	    if(nstabs != 0)
		printf(" has %lu debugging symbols and %lu string "
		       "bytes\n", nstabs, stab_strings);
	}
	if(cmd_flags->verification == TRUE)
	    printf("unstripped_binary\n");
	if(cmd_flags->trey == TRUE && nstabs == 0)
	    return;

	exit_status = EXIT_FAILURE;
	return;
}