📄 resolve.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * @(#)resolve.c (solib) * * Shared object(SO)support library * Search/link of symbol */#include <string.h>#include "so.h"#include "symtbl.h"#define TSD_SOL_IDX_M1 (-1)/* * Symbol information */typedef struct { DLInfo *dlp; /* Object where symbol exists */ Elf32_Sym *sym; /* Symbol table entry */} DLSymbol;Inline Elf32_Sym* lookup( DLInfo *dlp, UB *name, UW hash, UW reltype );LOCAL BOOL scopelookup( DLScope *scope, W idx, UB *name, UW hash, UW reltype, DLSymbol *syminf );/* * Symbol search * dlp Look-up object * name Symbol name * hash Symbol hash value * reltype Symbol relocation type * Return value Symbol entry of serach results * NULL when it is not found */Inline Elf32_Sym* lookup( DLInfo *dlp, UB *name, UW hash, UW reltype ){ Elf32_Sym *sym; UW idx; /* In search of "COPY" symbol, exclude the main program from the look-up object. Main program can be a copy destination only. */#ifdef IS_MAIN_SYMBOL if (IS_MAIN_SYMBOL(reltype, dlp)) { return NULL; }#endif /* Search from the symbol hash */ for ( idx = dlp->hash.bucket[hash % dlp->hash.nbucket]; idx != (UW)STN_UNDEF; idx = dlp->hash.chain[idx] ) { sym = &dlp->symtab[idx]; /* Disregard the undefined symbol */ if ( sym->st_shndx == SHN_UNDEF ) { continue; } /* Disregard the symbol type other than that of STT_NOTYPE,OBJECT,and FUNC */ if ( ELF32_ST_TYPE(sym->st_info) > STT_FUNC ) { continue; } /* Check if symbol name is completely correspondent or not */ if ( strcmp((char*)(dlp->strtab + sym->st_name), (char*)name) != 0 ) { continue; } return sym; /* Found */ } return NULL; /* Not found */}/* * Search of the symbol from the scope list * scope Scope list * idx Search start up location of scope list * name Symbol name * hash Symbol hash value * reltype SymbolRelocation type * sym Return the serach results (the symbol found) * Return value >= 0 Symbol type found (STB_xxx) * = -1 Not found */LOCAL BOOL scopelookup( DLScope *scope, W idx, UB *name, UW hash, UW reltype, DLSymbol *syminf ){ Elf32_Sym *sym; for ( ; idx < scope->nent; ++idx ) { sym = lookup(scope->ent[idx], name, hash, reltype); if ( sym == NULL ) { continue; } switch ( ELF32_ST_BIND(sym->st_info) ) { case STB_WEAK: /* Use the "WEAK"symbol that is firstly found in case * "GLOBAL" symbol is not defined. * Use the "GLOBAL" symbol if there is. */ if ( syminf->sym == NULL ) { syminf->sym = sym; syminf->dlp = scope->ent[idx]; } break; case STB_GLOBAL: syminf->sym = sym; syminf->dlp = scope->ent[idx]; return TRUE; /* Found */ default: /* nothing to do */ break; } } return FALSE; /* Not found */}/* * Acquisition of symbol value ( Symbol link) * dlp The object where the symbol is attached * name Symbol name * reltype Symbol relocation type * sym Return the symbol of search results (NULL when it is not found) * Return value Symbol value(Adjustment of"load offset" is done already) */EXPORT UW __so_resolve( DLInfo *dlp, UB *name, UW reltype, Elf32_Sym **sym ){ DLScope **scope; UW hash; DLSymbol syminf; DM("__so_resolve\n"); hash = Elf_hash(name); syminf.sym = NULL; for ( scope = dlp->scope; *scope != NULL; scope++ ) { if ( scopelookup(*scope, 0, name, hash, reltype, &syminf) != 0 ) { break; } } *sym = syminf.sym; if ( *sym == NULL ) { return 0; /* Not found */ } return (UW)syminf.sym->st_value + (UW)syminf.dlp->ldofs;}/* * Acquisition of the local symbol value * dlp Target object * name Symbol name * skip Non-target object * sym Return the search results (NULL when it is not found) * Return value Symbol value (Adjustment of"load offset" is done already) * * skip != When it is NULL, The object that is loaded after the skip * shall be the look-up object of symbol. */EXPORT UW __so_localresolve( DLInfo *dlp, UB *name, DLInfo *skip, Elf32_Sym **sym ){ DLScope **scope; UW hash; DLSymbol syminf; W idx, i; DM("__so_localresolve\n"); hash = Elf_hash(name); idx = ( skip == NULL )? 0: TSD_SOL_IDX_M1; syminf.sym = NULL; for ( scope = dlp->lscope; *scope != NULL; scope++ ) { if ( idx < 0 ) { for ( i = 0; i < (*scope)->nent; i++ ) { if ( (*scope)->ent[i] == skip ) { idx = i + 1; break; } } if ( idx < 0 ) { continue; } } if ( scopelookup(*scope, idx, name, hash, 0, &syminf) != 0 ) { break; } idx = 0; } *sym = syminf.sym; if ( *sym == NULL ) { return 0; /* Not found */ } return (UW)syminf.sym->st_value + (UW)syminf.dlp->ldofs;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -