static orl_return CheckSymbol( orl_symbol_handle orl_sym_hnd ) /************************************************************/ { orl_symbol_binding binding; const char *name; orl_symbol_type type; unsigned char info; name = ORLSymbolGetName( orl_sym_hnd ); binding = ORLSymbolGetBinding( orl_sym_hnd ); if( binding == ORL_SYM_BINDING_GLOBAL || binding == ORL_SYM_BINDING_WEAK ) { type = ORLSymbolGetType( orl_sym_hnd ); info = ORLSymbolGetRawInfo( orl_sym_hnd ); if( (type & ORL_SYM_TYPE_UNDEFINED) == 0 ) { if( (type & ORL_SYM_CDAT_MASK) || binding == ORL_SYM_BINDING_WEAK ) { AddSym( name, SYM_WEAK, info ); } else { AddSym( name, SYM_STRONG, info ); } } else { unsigned_64 val64; ORLSymbolGetValue( orl_sym_hnd, &val64 ); if( val64.u._32[I64LO32] != 0 || val64.u._32[I64HI32] != 0 ) { AddSym( name, SYM_WEAK, info ); } } } else if( binding == ORL_SYM_BINDING_ALIAS ) { AddSym( name, SYM_WEAK, 0 ); } return( ORL_OKAY ); }
static orl_return CheckSymbol( orl_symbol_handle orl_sym_hnd ) /************************************************************/ { orl_symbol_binding binding; char *name; orl_symbol_type type; unsigned char info; name = ORLSymbolGetName( orl_sym_hnd ); binding = ORLSymbolGetBinding( orl_sym_hnd ); if( binding == ORL_SYM_BINDING_GLOBAL || binding == ORL_SYM_BINDING_WEAK ) { type = ORLSymbolGetType( orl_sym_hnd ); info = ORLSymbolGetRawInfo( orl_sym_hnd ); if( !( type & ORL_SYM_TYPE_UNDEFINED ) ) { if( type & ORL_SYM_CDAT_MASK || binding == ORL_SYM_BINDING_WEAK ) { AddSym( name, SYM_WEAK, info ); } else { AddSym( name, SYM_STRONG, info ); } } else if( ORLSymbolGetValue( orl_sym_hnd ) != 0 ) { AddSym( name, SYM_WEAK, info ); } } else if( binding == ORL_SYM_BINDING_ALIAS ) { AddSym( name, SYM_WEAK, 0 ); } return( ORL_OKAY ); }
static orl_return ProcSymbol( orl_symbol_handle symhdl ) /******************************************************/ { orl_symbol_type type; char *name; orl_symbol_value value; orl_sec_handle sechdl; symbol *sym; size_t namelen; sym_flags symop; extnode *newnode; segnode *snode; bool isweak; orl_symbol_handle assocsymhdl; symbol *assocsym; orl_symbol_binding binding; sechdl = ORLSymbolGetSecHandle( symhdl ); snode = FindSegNode( sechdl ); type = ORLSymbolGetType( symhdl ); name = ORLSymbolGetName( symhdl ); if( type & ORL_SYM_TYPE_FILE ) { if( (CurrMod->modinfo & MOD_GOT_NAME) == 0 ) { CurrMod->modinfo |= MOD_GOT_NAME; _LnkFree( CurrMod->name ); CurrMod->name = AddStringStringTable( &PermStrings, name ); } return( ORL_OKAY ); } if( type & ORL_SYM_TYPE_DEBUG ) return( ORL_OKAY ); if( type & (ORL_SYM_TYPE_OBJECT|ORL_SYM_TYPE_FUNCTION) || (type & (ORL_SYM_TYPE_NOTYPE|ORL_SYM_TYPE_UNDEFINED) && name != NULL)) { namelen = strlen( name ); if( namelen == 0 ) { BadObject(); } if( CurrMod->modinfo & MOD_IMPORT_LIB ) { ImpProcSymbol( snode, type, name, namelen ); return( ORL_OKAY ); } newnode = AllocNode( ExtNodes ); newnode->handle = symhdl; binding = ORLSymbolGetBinding( symhdl ); symop = ST_CREATE; if( binding == ORL_SYM_BINDING_LOCAL ) { symop |= ST_STATIC | ST_NONUNIQUE; } if( (type & ORL_SYM_TYPE_UNDEFINED) && binding != ORL_SYM_BINDING_ALIAS ){ symop |= ST_REFERENCE; } else { symop |= ST_NOALIAS; } sym = SymOp( symop, name, namelen ); CheckIfTocSym( sym ); if( type & ORL_SYM_TYPE_COMMON ) { value = ORLSymbolGetValue( symhdl ); sym = MakeCommunalSym( sym, value.u._32[I64LO32], false, true ); } else if( type & ORL_SYM_TYPE_UNDEFINED ) { DefineReference( sym ); isweak = false; switch( binding ) { case ORL_SYM_BINDING_WEAK: isweak = true; case ORL_SYM_BINDING_ALIAS: case ORL_SYM_BINDING_LAZY: assocsymhdl = ORLSymbolGetAssociated( symhdl ); name = ORLSymbolGetName( assocsymhdl ); namelen = strlen(name); if( binding == ORL_SYM_BINDING_ALIAS ) { MakeSymAlias( sym->name, strlen(sym->name), name, namelen ); } else { assocsym = SymOp( ST_CREATE | ST_REFERENCE, name, namelen ); DefineLazyExtdef( sym, assocsym, isweak ); newnode->isweak = true; } } } else { newnode->isdefd = true; value = ORLSymbolGetValue( symhdl ); if( (type & ORL_SYM_TYPE_COMMON) && (type & ORL_SYM_TYPE_OBJECT) && sechdl == NULL) { sym = MakeCommunalSym( sym, value.u._32[I64LO32], false, true ); } else if( snode != NULL && snode->entry != NULL && snode->entry->iscdat ) { DefineComdatSym( snode, sym, value ); } else { sym->info |= SYM_DEFINED; DefineSymbol( sym, snode, value.u._32[I64LO32], 0 ); } } newnode->entry = sym; } else if( (type & ORL_SYM_TYPE_SECTION) && (type & ORL_SYM_CDAT_MASK) && snode != NULL && !(snode->info & SEG_DEAD) ) { snode->entry->select = (type & ORL_SYM_CDAT_MASK) >> ORL_SYM_CDAT_SHIFT; }
orl_return PrintSymbolInfo( orl_symbol_handle symbol ) /****************************************************/ { orl_symbol_type type; char *name; orl_sec_handle sec; name = ORLSymbolGetName( symbol ); //printf( "handle = %x", symbol ); printf( "%-25s:", name ? name : "" ); printf( " %8.8llx ", ORLSymbolGetValue( symbol ) ); switch( ORLSymbolGetBinding( symbol ) ) { case ORL_SYM_BINDING_NONE: printf( "n/a " ); break; case ORL_SYM_BINDING_LOCAL: printf( "locl" ); break; case ORL_SYM_BINDING_WEAK: printf( "weak" ); break; case ORL_SYM_BINDING_GLOBAL: printf( "glbl" ); break; case ORL_SYM_BINDING_LAZY: printf( "lazy" ); break; case ORL_SYM_BINDING_ALIAS: printf( "alis" ); break; } printf( " " ); type = ORLSymbolGetType( symbol ); if( type & ORL_SYM_TYPE_DEBUG ) { printf( "debug" ); } else if( type & ORL_SYM_TYPE_UNDEFINED ) { printf( "undef" ); } else if( type & ORL_SYM_TYPE_COMMON ) { printf( "comm " ); } else if( type & ORL_SYM_TYPE_ABSOLUTE ) { printf( "abs " ); } else { printf( " " ); } printf( " " ); if( type & ORL_SYM_TYPE_OBJECT ) { printf( "obj " ); } else if( type & ORL_SYM_TYPE_FUNCTION ) { printf( "func" ); } else if( type & ORL_SYM_TYPE_SECTION ) { printf( "sect" ); } else if( type & ORL_SYM_TYPE_FILE ) { printf( "file" ); } else { printf( "none" ); } sec = ORLSymbolGetSecHandle( symbol ); if( sec ) { printf( " (in '%s')", ORLSecGetName( sec ) ); } printf( "\n" ); return( ORL_OKAY ); }
orl_return CreateNamedLabel( orl_symbol_handle sym_hnd ) { hash_data * data_ptr; label_list sec_label_list; label_entry entry; orl_symbol_type type; orl_symbol_type primary_type; orl_sec_handle sec; char * SourceName; char * LabName; unsigned_64 val64; type = ORLSymbolGetType( sym_hnd ); primary_type = type & 0xFF; switch( primary_type ) { // No harm in including these since elf generates relocs to these. // case ORL_SYM_TYPE_NONE: // case ORL_SYM_TYPE_FUNC_INFO: // return( ORL_OKAY ); case ORL_SYM_TYPE_FILE: SourceName = ORLSymbolGetName( sym_hnd ); if( (SourceName != NULL) && (SourceFileInObject == NULL) ) { SourceFileInObject = SourceName; } return( ORL_OKAY ); } entry = MemAlloc( sizeof( label_entry_struct ) ); if( !entry ) return( ORL_OUT_OF_MEMORY ); val64 = ORLSymbolGetValue( sym_hnd ); entry->offset = val64.u._32[I64LO32]; // all symbols from the object file will have names entry->shnd = ORLSymbolGetSecHandle( sym_hnd ); if( primary_type == ORL_SYM_TYPE_SECTION ) { entry->type = LTYP_SECTION; } else if( primary_type == ORL_SYM_TYPE_GROUP ) { entry->type = LTYP_GROUP; } else if( entry->shnd == 0 ) { entry->type = LTYP_EXTERNAL_NAMED; } else if( primary_type == ORL_SYM_TYPE_FUNC_INFO ){ entry->type = LTYP_FUNC_INFO; } else { entry->type = LTYP_NAMED; } entry->binding = ORLSymbolGetBinding( sym_hnd ); LabName = ORLSymbolGetName( sym_hnd ); if( LabName == NULL ) { sec = ORLSymbolGetSecHandle( sym_hnd ); if( sec ) { LabName = ORLSecGetName( sec ); } else { MemFree( entry ); return( ORL_OKAY ); } } // Demangle the name, if necessary if( !((Options & NODEMANGLE_NAMES) || (DFormat & DFF_ASM)) ) { entry->label.name = MemAlloc( MAX_LINE_LEN + 3 ); __demangle_l( LabName, 0, &(entry->label.name[2]), MAX_LINE_LEN ); } else { entry->label.name = MemAlloc( strlen( LabName )+8 ); strcpy( &(entry->label.name[2]), LabName ); } entry->label.name[0]=0; entry->label.name[1]=0; LabName = &(entry->label.name[2]); if( NeedsQuoting( LabName ) ) { // entry->label.name[-1] will be 1 if we have added a quote, // 0 otherwise. This is helpful when freeing the memory. entry->label.name[0] = 1; entry->label.name[1] = '`'; entry->label.name += 1; LabName += strlen( LabName ); LabName[0] = '`'; LabName[1] = '\0'; } else { entry->label.name += 2; } data_ptr = HashTableQuery( HandleToLabelListTable, (hash_value) entry->shnd ); if( data_ptr ) { sec_label_list = (label_list) *data_ptr; entry = addLabel( sec_label_list, entry, sym_hnd ); if( Options & PRINT_PUBLICS && entry->shnd != 0 && primary_type != ORL_SYM_TYPE_SECTION && entry->binding != ORL_SYM_BINDING_LOCAL ) { Publics.number++; } } else { // error!!!! the label list should have been created MemFree( entry ); return( ORL_ERROR ); } return( ORL_OKAY ); }