/* output import stubs for exported entry points that link to external symbols */ static void output_external_link_imports( DLLSPEC *spec ) { unsigned int i, pos; if (!ext_link_imports.count) return; /* nothing to do */ sort_names( &ext_link_imports ); /* get rid of duplicate names */ for (i = 1; i < ext_link_imports.count; i++) { if (!strcmp( ext_link_imports.names[i-1], ext_link_imports.names[i] )) remove_name( &ext_link_imports, i-- ); } output( "\n/* external link thunks */\n\n" ); output( "\t.data\n" ); output( "\t.align %d\n", get_alignment(get_ptr_size()) ); output( ".L__wine_spec_external_links:\n" ); for (i = 0; i < ext_link_imports.count; i++) output( "\t%s %s\n", get_asm_ptr_keyword(), asm_name(ext_link_imports.names[i]) ); output( "\n\t.text\n" ); output( "\t.align %d\n", get_alignment(get_ptr_size()) ); output( "%s:\n", asm_name("__wine_spec_external_link_thunks") ); for (i = pos = 0; i < ext_link_imports.count; i++) { char *buffer = strmake( "__wine_spec_ext_link_%s", ext_link_imports.names[i] ); output_import_thunk( buffer, ".L__wine_spec_external_links", pos ); free( buffer ); pos += get_ptr_size(); } output_function_size( "__wine_spec_external_link_thunks" ); }
/* resolve the imports for a Win32 module */ void resolve_imports( DLLSPEC *spec ) { int i; unsigned int j, removed; ORDDEF *odp; check_undefined_forwards( spec ); for (i = 0; i < nb_imports; i++) { struct import *imp = dll_imports[i]; for (j = removed = 0; j < undef_symbols.count; j++) { odp = find_export( undef_symbols.names[j], imp->exports, imp->nb_exports ); if (odp) { if (odp->flags & FLAG_PRIVATE) continue; if (odp->type != TYPE_STDCALL && odp->type != TYPE_CDECL) warning( "winebuild: Data export '%s' cannot be imported from %s\n", odp->link_name, imp->spec->file_name ); else { add_import_func( imp, odp ); remove_name( &undef_symbols, j-- ); removed++; } } } if (!removed) { /* the dll is not used, get rid of it */ if (check_unused( imp, spec )) warning( "winebuild: %s imported but no symbols used\n", imp->spec->file_name ); remove_import_dll( i ); i--; } } sort_names( &undef_symbols ); check_undefined_exports( spec ); }
/*========================================== * check_ghosts -- Process all names & refns * checking (& optionally fixing) ghosts * Created: 2001/01/01, Perry Rapp *=========================================*/ static void check_ghosts (void) { tofix = create_list(); soundexseq = create_indiseq_sval(); /* soundexseq is used inside cgn_callback, across calls */ traverse_names(cgn_callback, NULL); finish_and_delete_nameset(); if (todo.fix_ghosts) { NAMEREFN_REC * rec; while (!is_empty_list(tofix)) { rec = (NAMEREFN_REC *) dequeue_list(tofix); remove_name(rec->namerefn, rec->key); ++errs[rec->err].fix_count; free_namerefn(rec); } } ASSERT(is_empty_list(tofix)); ASSERT(!soundexseq); soundexseq = create_indiseq_sval(); /* soundexseq is used inside cgr_callback, across calls */ traverse_refns(cgr_callback, NULL); finish_and_delete_refnset(); if (todo.fix_ghosts) { NAMEREFN_REC * rec; while (!is_empty_list(tofix)) { rec = (NAMEREFN_REC *) dequeue_list(tofix); remove_refn(rec->namerefn, rec->key); free_namerefn(rec); } } destroy_list(tofix); tofix=0; }
int mv () { if (!out[1]) { printf("Usage: cp SRC DEST\n"); return -1; } if (!out[2]) { printf("Missing target destination.\n"); return -2; } if (strcmp(out[1], out[2]) == 0) { printf("Cannot move a file into itself.\n"); return -3; } int ino, p_ino, sp_ino, src_dev = running->cwd->dev, dest_dev = running->cwd->dev, src_parent_dev = src_dev; char src[INODE_NAME*2], dest[INODE_NAME*2], dest_parent_path[INODE_NAME*2], src_parent_path[INODE_NAME*2]; strcpy(src, out[1]); strcpy(dest, out[2]); strcpy(src_parent_path, dirname(out[1])); strcpy(dest_parent_path, dirname(out[2])); if (out[2][0] == '/') { src_parent_dev = src_dev = root->dev; dest_dev = root->dev; } p_ino = get_inode(dest_parent_path, &dest_dev, FALSE); // Make sure that the destination's parent exists if (p_ino < 0) { printf("\"%s\" : parent directory does not exist.\n", basename(dest_parent_path)); return -4; } ino = get_inode(dest, &dest_dev, TRUE); // Make sure that the destination file does not already exist if (ino > 0) // Destination file already exists { printf("\"%s\" : file already exists with this name.\n", dest); return -4; } ino = get_inode(src, &src_dev, FALSE); // Make sure that the source file does exist if (ino < 0) { return ino; } sp_ino = get_inode(src_parent_path, &src_parent_dev, TRUE); MINODE *mip = iget(src_dev, ino); MINODE *d_pip = iget(dest_dev, p_ino); MINODE *s_pip = iget(src_dev, sp_ino); if (src_dev == dest_dev) // the source and destination are on the same device { enter_name(d_pip, ino, basename(dest), mip->Inode.i_mode); d_pip->dirty = TRUE; mip->dirty = TRUE; remove_name(s_pip, mip->ino, basename(src)); } else { _cp(src, dest); mip->Inode.i_links_count--; if (mip->Inode.i_links_count == 0) { __unlink(mip, s_pip, basename(src)); } remove_name(s_pip, mip->ino, basename(src)); if (DEBUGGING) debug_dir(s_pip); s_pip->Inode.i_atime = time(0L); s_pip->dirty = TRUE; mip->dirty = TRUE; } // TODO: moving files across devices iput(mip); iput(d_pip); iput(s_pip); return 0; }