⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reloc.c

📁 T-kernel 的extension源代码
💻 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 + -