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

📄 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_Rela *rela, UW size );Inline ER relocate( DLInfo *dlp, UW lazy );LOCAL ER relocsection( DLInfo *dlp, Elf32_Rela *rela, UW size );#define TSD_RLO_GOT_1	1#define TSD_RLO_GOT_2	2/* * 1 section relocation and symbol link */LOCAL ER relocsection( DLInfo *dlp, Elf32_Rela *rela, UW size ){	Elf32_Rela	*end = rela + (size / sizeof(Elf32_Rela));	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;	UW		*uwp;		for ( ; rela < end; rela++ ) {		type = ELF32_R_TYPE(rela->r_info);		wp = (UW*)((UB *)(rela->r_offset) + ldofs);		switch ( type ) {		  case R_SH_NONE:		  	continue;		  case R_SH_RELATIVE:			if (rela->r_addend != 0) {				*wp = (UW)((UW*)ldofs + rela->r_addend);			} else {				*wp += (UW)ldofs;			}			continue;		  default:			/* nothing to do */			break;		}		symno = ELF32_R_SYM(rela->r_info);		/* Symbol value acquisition (link of symbol) */		name = strtab + symtab[symno].st_name;		val = __so_resolve(dlp, name, type, &sym);		/* The undefined symbol excepting "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_SH_JMP_SLOT:			/* Store the symbol value */			uwp = (UW*)((UB *)(rela->r_offset) + ldofs);			*uwp = val;			break;		  case R_SH_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;		  case R_SH_GOT32:		  case R_SH_DIR32:			tmp = val + (UW)rela->r_addend;			if ( *wp != tmp ) {				*wp = tmp;			}			break;		  case R_SH_REL32:			tmp = (UW)((UW *)(val + (UW)rela->r_addend) - wp);			if (*wp != tmp) {				*wp = tmp;			}			break;		  case R_SH_GLOB_DAT:			tmp = (UW)((UW*)val + rela->r_addend);			if (*wp != tmp) {				*wp = tmp;			}			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 1 section (only) */Inline void lazy_relocsection( DLInfo *dlp, Elf32_Rela *rela, UW size ){	Elf32_Rela	*end = rela + (size / sizeof(Elf32_Rela));	W		ldofs = dlp->ldofs;	UW		*uwp;	for ( ; rela < end; rela++ ) {		/* Everything should be R_SH_JMP_SLOT */		uwp = (UW*)((UB *)(rela->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 sequesntial link of symbol */		dlp->got[TSD_RLO_GOT_1] = dlp;		dlp->got[TSD_RLO_GOT_2] = (VP)__so_runtime_resolve;	}	/* DT_RELA relocation and symbol link */	err = relocsection(dlp, dlp->relatab, dlp->relasz);	if ( err < E_OK ) {		goto err_ret;	}	if ( (lazy == 0U) || (__so_LazyMode == 0) ) {		/* DT_PLTREL relocation and symbol link */		err = relocsection(dlp, (Elf32_Rela *)dlp->jreltab, dlp->jrelsz);		if ( err < E_OK ) {			goto err_ret;		}	} else {		/* DT_PLTREL relocation only  */		lazy_relocsection(dlp, (Elf32_Rela *)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;	/* 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 + -