📄 elfcore.c
字号:
read_len = 0;
while( read_len < phdr->p_filesz ) {
lseek( fd, phdr->p_offset + read_len, SEEK_SET );
if( read( fd, note, sizeof( Elf_Note ) ) != sizeof( Elf_Note ) ) {
break;
}
read_len += sizeof( Elf_Note );
if( swap ) {
SWAP_32( note->n_namesz );
SWAP_32( note->n_descsz );
SWAP_32( note->n_type );
}
if( note->n_type == ntype ) {
/* Found our note, allocate memory for name and read it */
name = malloc( note->n_namesz );
if( name ) {
read( fd, name, note->n_namesz );
/* Skip over padding so that caller can read note data */
skip = ((note->n_namesz + ELF_ROUND) & ~ELF_ROUND) - note->n_namesz;
lseek( fd, skip, SEEK_CUR );
}
break;
}
/* Skip over note contents */
read_len += (note->n_namesz + ELF_ROUND) & ~ELF_ROUND;
read_len += (note->n_descsz + ELF_ROUND) & ~ELF_ROUND;
}
}
return( name );
}
static int load_elf_header( const char *core_name, Elf32_Ehdr *ehdr, Elf32_Phdr **pphdr )
{
int fd;
fd = open( core_name, O_RDONLY | O_BINARY );
if( fd < 0 ) {
return( NO_FILE );
}
if( !elf_read_hdr( fd, ehdr ) ) {
close( fd );
fd = NO_FILE;
} else {
if( !elf_read_phdr( fd, ehdr, pphdr ) ) {
close( fd );
fd = NO_FILE;
}
}
return( fd );
}
static int init_platform_driver( int fd, Elf32_Ehdr *ehdr, Elf32_Phdr *phdr )
{
void *ctx;
int result = FALSE;
plat_drv_t **drv;
for( drv = drivers; *drv; ++drv ) {
ctx = (*drv)->init( fd, ehdr, phdr );
if( ctx ) {
Core.plat = *drv;
Core.ctx = ctx;
result = TRUE;
break;
}
}
return( result );
}
static void close_platform_driver( void )
{
if( Core.plat ) {
Core.plat->done( Core.ctx );
Core.ctx = NULL;
Core.plat = NULL;
}
}
unsigned ReqProg_load( void )
{
prog_load_req *acc;
prog_load_ret *ret;
char *argv;
Core.mapping_shared = FALSE;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
argv = GetInPtr( sizeof( *acc ) );
ret->mod_handle = MH_DEBUGGEE;
ret->task_id = 0;
if( argv[0] == '\0' ) {
ret->err = ENOENT;
return( sizeof( *ret ) );
}
Core.err_no = 0;
Core.fd = load_elf_header( argv, Core.c_ehdr, &Core.c_phdr );
if( (Core.fd == NO_FILE) || !init_platform_driver( Core.fd, Core.c_ehdr, Core.c_phdr ) ) {
ret->err = ENOENT;
return( sizeof( *ret ) );
}
ret->flags = LD_FLAG_IS_STARTED | LD_FLAG_IS_PROT;
/* Tell debugger to ignore segment values when comparing pointers */
ret->flags |= LD_FLAG_IS_32 | LD_FLAG_IGNORE_SEGMENTS;
ret->err = Core.err_no;
ret->task_id = Core.plat->qpid( Core.ctx );
if( Core.err_no == 0 ) {
size_t len;
Core.loaded = TRUE;
/* If we have core, try setting up the executable file */
len = Core.plat->name( Core.ctx, Core.exe_name, MAX_FULLPATH_LEN );
if( len ) {
Core.x_fd = load_elf_header( Core.exe_name, Core.x_ehdr, &Core.x_phdr );
}
} else {
close( Core.fd );
Core.fd = NO_FILE;
}
return( sizeof( *ret ) );
}
unsigned ReqProg_kill( void )
{
prog_kill_ret *ret;
if( Core.loaded ) {
Core.loaded = FALSE;
close_platform_driver();
close( Core.fd );
if( Core.x_fd != NO_FILE ) {
close( Core.x_fd );
Core.x_fd = NO_FILE;
}
if( Core.c_phdr ) free( Core.c_phdr );
if( Core.x_phdr ) free( Core.x_phdr );
Core.fd = NO_FILE;
}
Core.mapping_shared = FALSE;
ret = GetOutPtr( 0 );
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqSet_break( void )
{
set_break_ret *ret;
ret = GetOutPtr( 0 );
ret->old = 0;
return( sizeof( *ret ) );
}
unsigned ReqClear_break( void )
{
return( 0 );
}
unsigned ReqSet_watch( void )
{
set_watch_ret *ret;
ret = GetOutPtr( 0 );
ret->err = 0;
ret->multiplier = USING_DEBUG_REG | 1;
return( sizeof( *ret ) );
}
unsigned ReqClear_watch( void )
{
return( 0 );
}
unsigned ReqProg_go( void )
{
prog_go_ret *ret;
ret = GetOutPtr( 0 );
/* Say the process is terminated, which will prevent
* the debugger from trying anything funny.
*/
ret->conditions = COND_TERMINATE;
return( sizeof( *ret ) );
}
unsigned ReqProg_step( void )
{
return( ReqProg_go() );
}
unsigned ReqGet_message_text( void )
{
get_message_text_ret *ret;
char *err_txt;
ret = GetOutPtr( 0 );
err_txt = GetOutPtr( sizeof( *ret ) );
err_txt[0] = '\0';
ret->flags = MSG_NEWLINE | MSG_ERROR;
return( sizeof( *ret ) + 1 );
}
unsigned ReqRedirect_stdin( void )
{
redirect_stdin_ret *ret;
ret = GetOutPtr( 0 );
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqRedirect_stdout( void )
{
return( ReqRedirect_stdin() );
}
unsigned ReqFile_string_to_fullpath( void )
{
unsigned_16 len;
char *name;
char *fullname;
file_string_to_fullpath_req *acc;
file_string_to_fullpath_ret *ret;
int fd;
Elf32_Ehdr ehdr;
Elf32_Phdr *phdr;
acc = GetInPtr( 0 );
name = GetInPtr( sizeof( *acc ) );
ret = GetOutPtr( 0 );
fullname = GetOutPtr( sizeof( *ret ) );
fullname[0] = '\0';
len = 0;
if( acc->file_type != TF_TYPE_EXE ) {
len = FindFilePath( FALSE, name, fullname );
} else if( Core.mapping_shared ) {
len = FindFilePath( TRUE, name, fullname );
} else {
fd = load_elf_header( name, &ehdr, &phdr );
if( (fd != NO_FILE) && init_platform_driver( fd, &ehdr, phdr ) ) {
len = Core.plat->name( Core.ctx, fullname, MAX_FULLPATH_LEN );
if( !len ) {
strcpy( fullname, "unknown" );
len = strlen( fullname );
} else {
#if 0
struct stat chk;
name = "/foo/bar"; //Core.hdr.psdata.un.proc.name;
if( stat( name, &chk ) != 0 ) {
chk.st_mtime = 0;
}
if( Core.ignore_timestamp || chk.st_mtime == Core.hdr.cmdtime ) {
len = StrCopy( name, fullname ) - fullname;
} else {
/* Executable and core file timestaps don't match */
len = 0;
}
#endif
}
close( fd );
}
}
if( len == 0 ) {
ret->err = ENOENT; /* File not found */
} else {
ret->err = 0;
}
return( sizeof( *ret ) + len + 1 );
}
unsigned ReqAddr_info( void )
{
addr_info_req *acc;
addr_info_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->is_32 = TRUE;
return( sizeof( *ret ) );
}
unsigned ReqMachine_data( void )
{
machine_data_req *acc;
machine_data_ret *ret;
unsigned_8 *data;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
data = GetOutPtr( sizeof( *ret ) );
ret->cache_start = 0;
ret->cache_end = ~(addr_off)0;
*data = X86AC_BIG;
return( sizeof( *ret ) + sizeof( *data ) );
}
unsigned ReqGet_lib_name( void )
{
get_lib_name_req *acc;
get_lib_name_ret *ret;
char *name;
// TODO: we ought to figure out what shared libs were loaded
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
name = GetOutPtr( sizeof( *ret ) );
switch( acc->handle ) {
case MH_NONE:
case MH_DEBUGGEE:
ret->handle = MH_SLIB;
strcpy( name, "/boot/sys/Slib32" );
break;
case MH_SLIB:
ret->handle = MH_PROC;
strcpy( name, "/boot/sys/Proc32" );
break;
default:
ret->handle = MH_NONE;
name[0] = '\0';
break;
}
return( sizeof( *ret ) + 1 + strlen( name ) );
}
#if 0
unsigned ReqThread_get_next( void )
{
thread_get_next_req *req;
thread_get_next_ret *ret;
req = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( req->thread == 0 ) {
ret->thread = Core.hdr.psdata.pid;
ret->state = THREAD_THAWED;
} else {
ret->thread = 0;
}
return( sizeof( *ret ) );
}
unsigned ReqThread_set( void )
{
thread_set_ret *ret;
ret = GetOutPtr( 0 );
ret->err = 0;
ret->old_thread = Core.hdr.psdata.pid;
return( sizeof( *ret ) );
}
unsigned ReqThread_freeze( void )
{
thread_freeze_ret *ret;
ret = GetOutPtr( 0 );
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqThread_thaw( void )
{
thread_thaw_ret *ret;
ret = GetOutPtr( 0 );
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqThread_get_extra( void )
{
char *ret;
ret = GetOutPtr( 0 );
ret[0] = '\0';
return( strlen( ret ) + 1 );
}
#endif
unsigned ReqGet_err_text( void )
{
get_err_text_req *acc;
char *err_txt;
// TODO: get platform specific messages for signals
err_txt = GetOutPtr( 0 );
acc = GetInPtr( 0 );
strcpy( err_txt, "Unknown error" );
return( strlen( err_txt ) + 1 );
}
trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
trap_version ver;
remote = remote;
Core.fd = NO_FILE;
Core.x_fd = NO_FILE;
Core.c_ehdr = malloc( sizeof( Elf32_Ehdr ) );
Core.x_ehdr = malloc( sizeof( Elf32_Ehdr ) );
if( parm != NULL ) {
while( *parm != '\0' ) {
switch( *parm ) {
case 'I':
case 'i':
Core.ignore_timestamp = TRUE;
break;
}
++parm;
}
}
err[0] = '\0'; /* all ok */
ver.major = TRAP_MAJOR_VERSION;
ver.minor = TRAP_MINOR_VERSION;
ver.remote = FALSE;
return( ver );
}
void TRAPENTRY TrapFini( void )
{
if( Core.c_ehdr ) free( Core.c_ehdr );
if( Core.x_ehdr ) free( Core.x_ehdr );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -