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 ); }
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) ) { 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, 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, 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, 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; }