📄 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 <string.h>#include "../../so.h"Inline void lazy_relocsection( DLInfo *dlp, Elf32_Rel *rel, UW size );Inline ER relocate( DLInfo *dlp, UW lazy );LOCAL ER relocsection( DLInfo *dlp, Elf32_Rel *rel, UW size );#define TSD_RLS_MSK_0XFF000000 0xff000000U#define TSD_RLS_MSK_0XFE000000 0xfe000000U#define TSD_RLS_MSK_0X00FFFFFF 0x00ffffffU#define TSD_RLS_SFT_2 2U#define TSD_RLC_POS_1 1#define TSD_RLC_POS_2 2#define TSD_RLS_MSK_0X00800000 0x00800000U/* * 1section relocation and symbol link */LOCAL ER relocsection( DLInfo *dlp, Elf32_Rel *rel, UW size ){ Elf32_Rel *end = rel + (size / sizeof(Elf32_Rel)); W ldofs = dlp->ldofs; UB *strtab = dlp->strtab; Elf32_Sym *symtab = dlp->symtab; Elf32_Sym *sym; UB *name; UW type, symno; UW *wp, val, tmp; ER err; for ( ; rel < end; rel++ ) { type = ELF32_R_TYPE(rel->r_info); wp = (UW*)((UB *)(rel->r_offset) + ldofs); switch ( type ) { case R_ARM_NONE: continue; case R_ARM_RELATIVE: *wp += (UW)ldofs; continue; default: /* nothing to do */ break; } symno = ELF32_R_SYM(rel->r_info); /* Symbol value acquisition (link of symbol value) */ name = strtab + symtab[symno].st_name; val = __so_resolve(dlp, name, type, &sym); /* The undefined symbol execpting "weak" attribute is error */ if ( (sym == NULL) && (ELF32_ST_BIND(symtab[symno].st_info) != STB_WEAK) ) { SYSLOG((LOG_ERR, "solib: %s is not defined", name)); err = E_REC; goto err_ret; } /* Relocation */ switch ( type ) { case R_ARM_PC24:{ UW addend; W newval; addend = *wp; if ( (addend & TSD_RLS_MSK_0X00800000) != 0 ) { addend |= TSD_RLS_MSK_0XFF000000; } newval = (W)(val - (UW)wp + ( addend << TSD_RLS_SFT_2 )); if ((( (UW)newval & TSD_RLS_MSK_0XFE000000) != TSD_RLS_MSK_0XFE000000) && (( (UW)newval & TSD_RLS_MSK_0XFE000000) != 0U)) { SYSLOG((LOG_ERR, "solib: relocation error (%s)", name)); err = E_REC; goto err_ret; } newval >>= TSD_RLS_SFT_2; *wp = (*wp & TSD_RLS_MSK_0XFF000000) | ((UW)newval & TSD_RLS_MSK_0X00FFFFFF); break; } case R_ARM_ABS32: { *wp += val; break; } case R_ARM_GLOB_DAT: case R_ARM_JUMP_SLOT: { *wp = val; break; } case R_ARM_COPY: { if ( sym == NULL ) { err = E_REC; goto err_ret; } if ( sym->st_size > symtab[symno].st_size ) { err = E_REC; goto err_ret; } memcpy(wp, (VP)val, sym->st_size); 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 err = %d\n", err)); return err;}/* * Relocation of 1section (only) */Inline void lazy_relocsection( DLInfo *dlp, Elf32_Rel *rel, UW size ){ Elf32_Rel *end = rel + (size / sizeof(Elf32_Rel)); W ldofs = dlp->ldofs; UW *uwp; for ( ; rel < end; rel++ ) { /* Everything should be R_ARM_JUMP_SLOT */ uwp = (UW*)((UB *)(rel->r_offset) + ldofs); *uwp += (UW)ldofs; }}/* * Relocation of 1 object */Inline ER relocate( DLInfo *dlp, UW lazy ){ ER err; if (dlp->got != NULL) { /* Register the runtime resolver for sequential link of symbol */ dlp->got[TSD_RLC_POS_1] = dlp; dlp->got[TSD_RLC_POS_2] = (VP)__so_runtime_resolve; } /* DT_REL relocation and symbol link */ err = relocsection(dlp, dlp->reltab, dlp->relsz); if ( err < E_OK ) { goto err_ret; } if ( (lazy == 0U) || (__so_LazyMode == 0) ) { /* DT_PLTREL relocation and symbol link */ err = relocsection(dlp, (Elf32_Rel *)dlp->jreltab, dlp->jrelsz); if ( err < E_OK ) { goto err_ret; } } else { /* DT_PLTREL relocation only */ lazy_relocsection(dlp, (Elf32_Rel *)dlp->jreltab, dlp->jrelsz); } dlp->relocated = TRUE; return E_OK;err_ret: DEBUG_PRINT(("relocate err = %d\n", err)); return err;}/* * Relocation of the entire load object */EXPORT ER __so_relocate( DLInfo *loader, UW lazy ){ QUEUE *q; DLInfo *dlp; ER err; DM("__so_relocalte\n"); /* Relocation is made in order of the latest loading */ q = &__dlInfo.q; do { dlp = (DLInfo*)(q = q->prev); if ( dlp->relocated != 0 ) { continue; } err = relocate(dlp, lazy); if ( err < E_OK ) { goto err_ret; } } 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 + -