7 #include "manes/manec.h"
9 #include "resources/fat.h"
11 typedef unsigned int Elf32_Addr
;
12 typedef unsigned short Elf32_Half
;
13 typedef unsigned int Elf32_Off
;
14 typedef signed int Elf32_Sword
;
15 typedef unsigned int Elf32_Word
;
46 Elf32_Word sh_addralign
;
47 Elf32_Word sh_entsize
;
65 #define R_386_GLOB_DAT 6
66 #define R_386_JMP_SLOT 7
72 unsigned char st_info
;
73 unsigned char st_other
;
77 #define ELF32_R_SYM(i) ((i)>>8)
78 #define ELF32_R_TYPE(i) ((unsigned char)(i))
79 #define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
81 struct Elf32_DynLinker
{
94 unsigned char e_ident
[ELF_NIDENT
]; /**< magic number */
95 Elf32_Half e_type
; /**< type of elf file */
96 Elf32_Half e_machine
; /**< hardware architecture */
97 Elf32_Word e_version
; /**< version of elf */
98 Elf32_Addr e_entry
; /**< entry point */
99 Elf32_Off e_phoff
; /**< offset of first program header */
100 Elf32_Off e_shoff
; /**< offset of first section header */
101 Elf32_Word e_flags
; /**< flags */
103 Elf32_Half e_phentsize
;
105 Elf32_Half e_shentsize
;
107 Elf32_Half e_shstrndx
;
110 modules::loader::module_entry
load_dynamic_elf(const char *prog
) {
111 char *buffer
= new char[0x1000 * 10];
112 Elf32_Ehdr
*header
= (Elf32_Ehdr
*)buffer
;
113 int offset
= (int)buffer
;
116 resources::fs
*fs_floppy
= manes::manec::get()->get_component(manes::component_name((manes::type_name
)"fat",0))->get
<resources::fs
>();
117 fs_floppy
->load_file(prog
, buffer
);
119 /* RELPTL (relocation table) [0x17] has to be filled with names addresses */
120 /* They are stored in DYNSYM (symbol table) [6] */
121 /* RELPTL and DYNSYM addresses are in dynamic section */
123 Elf32_Phdr
*segments
= (Elf32_Phdr
*)((int)header
->e_phoff
+ offset
);
125 /* Find dynamic segment in program */
126 Elf32_Dyn
*dynamic_s
= (Elf32_Dyn
*)0;
127 for (int i
= 0; i
< header
->e_phnum
; i
++)
128 if (segments
[i
].p_type
== PT_DYNAMIC
)
129 dynamic_s
= (Elf32_Dyn
*)(segments
[i
].p_offset
+ offset
);
131 /* Find relocation and symbol tables (sections) */
132 /* Checking for broken ELF files */
133 Elf32_Rel
*reldyn_t
= 0, *relplt_t
= 0;
134 int reldyn_size
= 0, relplt_size
= 0, rel_esize
= 0, reldyn_ent
= 0, relplt_ent
= 0;
135 Elf32_Sym
*symbol_t
= 0;
136 for (int i
= 0; dynamic_s
[i
].d_tag
; i
++) {
137 switch (dynamic_s
[i
].d_tag
) {
138 case DT_SYMTAB
: symbol_t
= (Elf32_Sym
*)(dynamic_s
[i
].d_un
.d_val
+ offset
); break;
139 case DT_REL
: reldyn_t
= (Elf32_Rel
*)(dynamic_s
[i
].d_un
.d_val
+ offset
); break;
140 case DT_JMPREL
: relplt_t
= (Elf32_Rel
*)(dynamic_s
[i
].d_un
.d_val
+ offset
); break;
141 case DT_RELENT
: rel_esize
= dynamic_s
[i
].d_un
.d_val
; break;
142 case DT_RELSZ
: reldyn_size
= dynamic_s
[i
].d_un
.d_val
; break;
143 case DT_PLTRELSZ
: relplt_size
= dynamic_s
[i
].d_un
.d_val
; break;
147 /* Fill offsets in REL (global variables) */
148 reldyn_ent
= reldyn_size
/ rel_esize
;
149 for (int i
= 0; i
< reldyn_ent
; i
++) {
150 u32
*record
= (u32
*)(reldyn_t
[i
].r_offset
+ offset
);
151 switch (ELF32_R_TYPE(reldyn_t
[i
].r_info
)) {
153 *record
+= symbol_t
[ELF32_R_SYM(reldyn_t
[i
].r_info
)].st_value
+ offset
- (u32
)record
;
157 *record
+= symbol_t
[ELF32_R_SYM(reldyn_t
[i
].r_info
)].st_value
+ offset
;
161 /* Fill offsets in RELPLT (procedures and functions) */
162 relplt_ent
= relplt_size
/ rel_esize
;
163 for (int i
= 0; i
< relplt_ent
; i
++) {
164 u32
*record
= (u32
*)(relplt_t
[i
].r_offset
+ offset
);
165 switch (ELF32_R_TYPE(relplt_t
[i
].r_info
)) {
167 *record
= symbol_t
[ELF32_R_SYM(relplt_t
[i
].r_info
)].st_value
+ offset
- (u32
)record
;
171 *record
= symbol_t
[ELF32_R_SYM(relplt_t
[i
].r_info
)].st_value
+ offset
;
175 /* Return entry point */
176 return (modules::loader::module_entry
)(header
->e_entry
+ offset
);