📄 reloc.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. * *---------------------------------------------------------------------- *//* * @(#)reloc.c (solib) * * Shared object(SO)support library * Relocation relation */#include "../../so.h"Inline VOID init_got( DLInfo *dlp );LOCAL ER relocsection_local( DLInfo *dlp, Elf32_Rel *rel, UW size );LOCAL ER relocsection_global( DLInfo *dlp );#define TSD_ING_I_2 2U/* * Local portion relocation and symbol link */LOCAL ER relocsection_local( DLInfo *dlp, Elf32_Rel *rel, UW size ){ Elf32_Rel *end = rel + (size / sizeof(Elf32_Rel)); W ldofs = dlp->ldofs; VP *got = dlp->got; Elf32_Sym *symtab = dlp->symtab; UW type, symno; UW *wp; ER err; for ( ; rel < end; rel++ ) { type = ELF32_R_TYPE(rel->r_info); if ( type == (UW)R_MIPS_NONE ) { continue; } symno = ELF32_R_SYM(rel->r_info); wp = (UW*)((UB *)(rel->r_offset) + ldofs); /* Relocation */ switch ( type ) { case R_MIPS_REL32: if ( symno != 0U ) { if (symno < dlp->mips_gotsym) { *wp += (UW)symtab[symno].st_value + (UW)ldofs; } else { *wp += (UW)got[symno + dlp->mips_local_gotno - dlp->mips_gotsym]; } } else { *wp += (UW)ldofs; } break; default: SYSLOG((LOG_ERR, "solib: unsupported relocation type (%d)", type)); err = E_REC; goto err_ret; } } return E_OK;err_ret: DEBUG_PRINT(("relocsection_local err = %d\n", err)); return err;}/********************************************************************************//* * "got" global portion relocation and symbol link */LOCAL ER relocsection_global( DLInfo *dlp ){ W ldofs = dlp->ldofs; UB *strtab = dlp->strtab; VP *got = dlp->got + dlp->mips_local_gotno; Elf32_Sym *syment = dlp->symtab + dlp->mips_gotsym; Elf32_Sym *symend = dlp->symtab + dlp->mips_symtabno; Elf32_Sym *sym; for ( ; syment < symend; syment++, got++ ) { if (syment->st_shndx == SHN_UNDEF) { if ((ELF32_ST_TYPE(syment->st_info) == STT_FUNC) && (syment->st_value != 0)) { *got = (VP)((UB *)(syment->st_value) + ldofs); } else { *got = (VP)__so_resolve( dlp, strtab + syment->st_name, 0, &sym); } } else if (syment->st_shndx == SHN_COMMON) { *got = (VP)__so_resolve( dlp, strtab + syment->st_name, 0, &sym); } else if ((ELF32_ST_TYPE(syment->st_info) == STT_FUNC) && (*got != syment->st_value)) { *got = (VP)((UB *)(*got) + ldofs); } else if (ELF32_ST_TYPE(syment->st_info) == STT_SECTION) { if (syment->st_other == 0) { *got = (VP)((UB *)(*got) + ldofs); } } else { *got = (VP)__so_resolve( dlp, strtab + syment->st_name, 0, &sym); } } return E_OK;}/********************************************************************************//* * "got" runtime resolver registration and "got" local portion relocation */Inline VOID init_got( DLInfo *dlp ){ UW i; VP *got = dlp->got; if ( !got ) { return; } /* Register the runtime resolver for sequential link of symbol */ got[0] = (VP)__so_runtime_resolve; got[1] = dlp; /* "got" local portion relocation */ for ( i = TSD_ING_I_2; i < dlp->mips_local_gotno; i++ ) { got[i] = (VP)((UB *)(got[i]) + dlp->ldofs); }}/********************************************************************************//* * Relocation of the entire load object * "lazy" is null. It constantly should be "lazy binding". */EXPORT ER __so_relocate( DLInfo *loader, UW lazy ){ QUEUE *q; DLInfo *dlp; ER err; /* Relocation of global portion */ /* Relocation is done in order of the latest loading */ q = &__dlInfo.q; do { dlp = (DLInfo*)(q = q->prev); if ( dlp->relocated != 0U ) { continue; } /* Runtime resolver registration and "got"local portion relocation */ init_got(dlp); /* "got" global portion relocation */ err = relocsection_global(dlp); if ( err < E_OK ) { goto err_ret; } /* local portion relocation */ err = relocsection_local(dlp, dlp->reltab, dlp->relsz); if ( err < E_OK ) { goto err_ret; } dlp->relocated = TRUE; } while ( q != &loader->q ); return E_OK;err_ret: DEBUG_PRINT(("__so_relocate err = %d\n", err)); return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -