34,6 → 34,10 |
* @file |
*/ |
|
void __main(void); |
void __io_init(void); |
void __exit(void); |
|
void _rtld_main(void); |
|
#define ELF32_R_SYM(i) ((i)>>8) |
91,6 → 95,8 |
|
elf32_sym *sym_table; |
elf32_rel *rel_table; |
elf32_rel *jmp_rel_table; |
elf32_rel *jmp_rel_entries; |
|
asm volatile ( |
"movl $30, %eax;" |
108,11 → 114,13 |
|
asm volatile ( |
/* Calculate the bias into %0 */ |
/* Generates "fake" R_386_RELATIVE run-time relocation */ |
" call .L0;" |
".L0: pop %0;" |
" subl $.L0, %0;" |
|
/* Calculate run-time address of _DYNAMIC into %1 */ |
/* Generates "fake" R_386_RELATIVE run-time relocation */ |
" movl $_DYNAMIC, %1;" /* Again, at link time 0-based VMA gets in */ |
" addl %0, %1;" /* Add bias to compute run-time address */ |
|
127,6 → 135,8 |
sym_table = 0; |
rel_table = 0; |
rel_entries = 0; |
jmp_rel_table = 0; |
jmp_rel_entries = 0; |
|
i = 0; |
while (dynamic[i].d_tag != 0) { |
134,6 → 144,8 |
dval = dynamic[i].d_un.d_val; |
|
switch (dynamic[i].d_tag) { |
case 2/* DT_PLTRELSZ */: jmp_rel_entries = dval/8; break; |
case 23/* DT_JMPREL */: jmp_rel_table = dptr; break; |
case 3 /* DT_PLTGOT */: |
/* GOT address */ |
got = dptr; break; |
164,7 → 176,9 |
kputint(rel_type); |
kputint(r_offset); |
|
if (rel_type == 7 /* R_386_JUMP_SLOT */) { |
switch (rel_type) { |
case 6: /* R_386_GLOB_DAT */ |
case 7: /* R_386_JUMP_SLOT */ |
kputint(16); |
sym_idx = ELF32_R_SYM(r_info); |
|
173,15 → 187,83 |
kputint(sym_addr); |
|
*(unsigned *)(r_offset+bias) = sym_addr; |
break; |
|
case 1: /* R_386_32 */ |
kputint(16); |
sym_idx = ELF32_R_SYM(r_info); |
|
sym_addr = sym_table[sym_idx].st_value + bias; |
kputint(sym_idx); |
kputint(sym_addr); |
|
*(unsigned *)(r_offset+bias) += sym_addr; |
break; |
|
case 8: /* R_386_RELATIVE */ |
kputint(16); |
*(unsigned *)(r_offset+bias) += bias; |
break; |
} |
} |
|
kputint(-1); |
|
for (i=0; i<jmp_rel_entries; i++) { |
kputint(i); |
r_offset = jmp_rel_table[i].r_offset; |
r_info = jmp_rel_table[i].r_info; |
|
kputint(32); |
rel_type = ELF32_R_TYPE(r_info); |
|
kputint(rel_type); |
kputint(r_offset); |
|
switch (rel_type) { |
case 6: /* R_386_GLOB_DAT */ |
case 7: /* R_386_JUMP_SLOT */ |
kputint(16); |
sym_idx = ELF32_R_SYM(r_info); |
|
sym_addr = sym_table[sym_idx].st_value + bias; |
kputint(sym_idx); |
kputint(sym_addr); |
|
*(unsigned *)(r_offset+bias) = sym_addr; |
break; |
|
case 1: /* R_386_32 */ |
kputint(16); |
sym_idx = ELF32_R_SYM(r_info); |
|
sym_addr = sym_table[sym_idx].st_value + bias; |
kputint(sym_idx); |
kputint(sym_addr); |
|
*(unsigned *)(r_offset+bias) += sym_addr; |
break; |
|
case 8: /* R_386_RELATIVE */ |
kputint(16); |
*(unsigned *)(r_offset+bias) += bias; |
break; |
} |
} |
|
kputint(-1); |
|
/* Init libc and run rtld main */ |
__main(); |
|
kputint(33); |
__io_init(); |
kputint(34); |
_rtld_main(); |
kputint(35); |
__exit(); |
|
kputint(36); |
|
asm ( |
"movl $250, %%eax;" |
"int $0x30" |