-
Notifications
You must be signed in to change notification settings - Fork 164
Expand file tree
/
Copy pathelf_loader_stdio.c
More file actions
103 lines (92 loc) · 2.85 KB
/
Copy pathelf_loader_stdio.c
File metadata and controls
103 lines (92 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
# _____ ___ ____ ___ ____
# ____| | ____| | | |____|
# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
#-----------------------------------------------------------------------
# Copyright ps2dev - http://www.ps2dev.org
# Licenced under Academic Free License version 2.0
# Review ps2sdk README & LICENSE files for further details.
*/
#include "elf_loader_common.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct elf_loader_reader_info_stdio_
{
FILE *m_fp;
elf_loader_reader_info_t m_reader_info;
elf_loader_reader_info_stdio_resultbuf_t m_resultbuf;
} elf_loader_reader_info_stdio_t;
static void *elf_loader_reader_read_elf_file_stdlib_allocation_callback(
void *userdata, void *pointer, ptrdiff_t old_size, ptrdiff_t new_size)
{
void *new_ptr;
(void)userdata;
(void)old_size;
if ( !new_size )
{
free(pointer);
return NULL;
}
new_ptr = realloc(pointer, new_size);
if ( !new_ptr )
{
free(pointer);
}
return new_ptr;
}
static int elf_loader_reader_read_elf_file_stdio_read_callback(
void *userdata, elf_loader_reader_stage_t stage, const elf_loader_reader_segment_info_t *segm_info, size_t segm_count)
{
elf_loader_reader_info_stdio_t *procinfo;
size_t i;
procinfo = (elf_loader_reader_info_stdio_t *)userdata;
if ( !procinfo->m_fp )
return 0;
for ( i = 0; i < segm_count; i += 1 )
{
if ( fseek(procinfo->m_fp, segm_info[i].m_segment_offset, SEEK_SET) )
{
return 0;
}
if ( ftell(procinfo->m_fp) != segm_info[i].m_segment_offset )
{
return 0;
}
if ( fread(segm_info[i].m_segment_addr, segm_info[i].m_segment_size, 1, procinfo->m_fp) != 1 )
{
return 0;
}
}
return 1;
}
static void
elf_loader_reader_read_elf_file_stdio_result_callback(void *userdata, void *pointer, ptrdiff_t pointer_size, int errval)
{
elf_loader_reader_info_stdio_t *procinfo;
procinfo = (elf_loader_reader_info_stdio_t *)userdata;
procinfo->m_resultbuf.m_buf = pointer;
procinfo->m_resultbuf.m_bufsize = pointer_size;
procinfo->m_resultbuf.m_result = errval;
}
int elf_loader_reader_read_elf_file_stdio(
elf_loader_reader_info_stdio_resultbuf_t *resultbuf, const char *filename, const char *flags)
{
elf_loader_reader_info_stdio_t procinfo;
procinfo.m_reader_info.m_userdata = &procinfo;
procinfo.m_reader_info.m_alloc_callback = elf_loader_reader_read_elf_file_stdlib_allocation_callback;
procinfo.m_reader_info.m_read_callback = elf_loader_reader_read_elf_file_stdio_read_callback;
procinfo.m_reader_info.m_result_callback = elf_loader_reader_read_elf_file_stdio_result_callback;
procinfo.m_fp = fopen(filename, flags);
if ( !procinfo.m_fp )
return -30;
elf_loader_reader_read_elf_file(&procinfo.m_reader_info);
if ( procinfo.m_fp )
{
fclose(procinfo.m_fp);
procinfo.m_fp = NULL;
}
if ( resultbuf )
*resultbuf = procinfo.m_resultbuf;
return procinfo.m_resultbuf.m_result;
}