Exemplo n.º 1
0
void BPatch_module::parseTypesIfNecessary() {
    if( moduleTypes != NULL ) { 
    	return;
    	}
    if (hasBeenRemoved_) return;
    
    moduleTypes = BPatch_typeCollection::getModTypeCollection( this );
	// /* DEBUG */ fprintf( stderr, "%s[%d]: parsing module '%s' @ %p (file %s) with type collection %p\n",	__FILE__, __LINE__, mod->fileName().c_str(), this, mod->obj()->fileName().c_str(), moduleTypes );

#if ! defined( USES_DWARF_DEBUG )
    if( BPatch::bpatch->parseDebugInfo() ) {
		parseTypes();
		}
#elif defined( arch_x86 ) || defined( arch_x86_64 ) || defined( arch_ia64 )
	/* I'm not actually sure about IA-64, but certainly on the other two,
	   it's legal and not uncommon to mix STABS and DWARF debug information
	   in the same file.  However, this causes problems because of the
	   differences in DWARF and STABS numeric type IDs.  In DWARF, the numeric
	   type IDs are unique accross the entire file, and are used to resolve
	   forward type references.  Thus, we parse all STABS debug information
	   before parsing any DWARF information.  Furthermore, DWARF requires
	   that all the BPatch_functions exist before parsing.  Thus... */
	   
	if( BPatch::bpatch->parseDebugInfo() ) {
        const pdvector< mapped_module  *> & map_mods = mod->obj()->getModules();
        
        /* Ensure all functions and type collections are defined. */
        for( unsigned i = 0; i < map_mods.size(); i++ ) {
            // use map_mods[i] instead of a name to get a precise match
            BPatch_module * bpmod = img->findOrCreateModule( map_mods[i] );
            assert( bpmod != NULL );

            bpmod->getProcedures();

			if( bpmod->moduleTypes == NULL ) {
				bpmod->moduleTypes = BPatch_typeCollection::getModTypeCollection( bpmod );
				}
            } /* end function instantiation */
		
		/* We'll need to have two loops anyway, so use three for clarity. */
        for( unsigned i = 0; i < map_mods.size(); i++ ) {
            // use map_mods[i] instead of a name to get a precise match
            BPatch_module * bpmod = img->findOrCreateModule( map_mods[i] );
            assert( bpmod != NULL );

            image * moduleImage = bpmod->mod->obj()->parse_img();
            assert( moduleImage != NULL );
            const Object & moduleObject = moduleImage->getObject();
            
            if( moduleObject.hasStabInfo() ) {
				/* This will blow away previous information, but not its own. */
				bpmod->parseStabTypes();

	            /* Therefore, blow away left-over STABS information to avoid type conflicts. */
    	        bpmod->moduleTypes->clearNumberedTypes();            
				}
            } /* end STABS parsing */

        for( unsigned i = 0; i < map_mods.size(); i++ ) {
            // use map_mods[i] instead of a name to get a precise match
            BPatch_module * bpmod = img->findOrCreateModule( map_mods[i] );
            assert( bpmod != NULL );
            
            image * moduleImage = bpmod->mod->obj()->parse_img();
            assert( moduleImage != NULL );
            const Object & moduleObject = moduleImage->getObject();
            
            if( moduleObject.hasDwarfInfo() ) { bpmod->parseDwarfTypes(); }            
			} /* end DWARF parsing */
		} /* end if we'rep parsing debug information at all */
#else 
	#error DWARF on platforms other than 86, x86-64, and IA-64 is unsupported.
#endif /* ! defined( USES_DWARF_DEBUG ) */
	return;
	} /* end parseTypesIfNecessary() */