version 1.2, 2014/03/29 11:10:52
|
version 1.3, 2014/04/04 11:25:37
|
Line 150 static int map_sections(int fd,const ehd
|
Line 150 static int map_sections(int fd,const ehd
|
__write2("section is both executable and writable, aborting!\n"); |
__write2("section is both executable and writable, aborting!\n"); |
return 1; |
return 1; |
} |
} |
if (p[i].p_flags&PF_X) { |
if (!(p[i].p_flags&PF_W)) { |
/* code segment */ |
/* code segment */ |
size_t ofs,len,rolen=0,nolen=0,rolen2=0,vaddr=p[i].p_vaddr,baseofs=0; |
size_t ofs,len,rolen=0,nolen=0,rolen2=0,vaddr=p[i].p_vaddr,baseofs=0; |
/* the first segment will be the code segment, and it will have |
/* the first segment will be the code segment, and it will have |
Line 204 static int map_sections(int fd,const ehd
|
Line 204 static int map_sections(int fd,const ehd
|
// D->s=(shdr*)(c+e->e_shoff); |
// D->s=(shdr*)(c+e->e_shoff); |
if (rolen>=4096) /* if we extended the mapping in the front, remove exec permissions */ |
if (rolen>=4096) /* if we extended the mapping in the front, remove exec permissions */ |
mprotect(c,rolen&~4095,PROT_READ); |
mprotect(c,rolen&~4095,PROT_READ); |
if (!vaddr) codeplus=(uintptr_t)(c+rolen); |
if (!vaddr && !codeplus) codeplus=(uintptr_t)(c+rolen); |
if (nolen) { |
if (nolen) { |
/* We mapped junk in the middle. |
/* We mapped junk in the middle. |
* If there are full pages in there, map them PROT_NONE */ |
* If there are full pages in there, map them PROT_NONE */ |
Line 304 static int map_sections(int fd,const ehd
|
Line 304 static int map_sections(int fd,const ehd
|
} |
} |
D->data=c+memsetstart; D->datalen=len-memsetstart; |
D->data=c+memsetstart; D->datalen=len-memsetstart; |
D->codeplus=codeplus; |
D->codeplus=codeplus; |
|
} else { |
|
__write2("can't happen error: LOAD segment that is neither code nor data.\n"); |
|
return 1; |
} |
} |
} |
} |
} |
} |
Line 458 static int loadlibs(struct dll* D) {
|
Line 461 static int loadlibs(struct dll* D) {
|
if (p[i].p_type==PT_DYNAMIC) { |
if (p[i].p_type==PT_DYNAMIC) { |
d=(dyn*)((char*)p[i].p_vaddr+D->codeplus); |
d=(dyn*)((char*)p[i].p_vaddr+D->codeplus); |
dnum=p[i].p_memsz/sizeof(dyn); |
dnum=p[i].p_memsz/sizeof(dyn); |
|
break; |
} |
} |
for (i=0; i<dnum; ++i) |
for (i=0; i<dnum; ++i) |
if (d[i].d_tag==DT_STRTAB) |
if (d[i].d_tag==DT_STRTAB) { |
dynstr=(char*)d[i].d_un.d_ptr+D->codeplus; |
dynstr=(char*)d[i].d_un.d_ptr+D->codeplus; |
|
break; |
|
} else if (d[i].d_tag==DT_NULL) |
|
break; |
|
|
/* we now have a dynamic section we can traverse */ |
/* we now have a dynamic section we can traverse */ |
for (i=0; i<dnum; ++i) { |
for (i=0; i<dnum; ++i) { |
Line 472 static int loadlibs(struct dll* D) {
|
Line 479 static int loadlibs(struct dll* D) {
|
__write2(" not found!\n"); |
__write2(" not found!\n"); |
exit(2); |
exit(2); |
} |
} |
} |
} else if (d[i].d_tag==DT_NULL) |
|
break; |
} |
} |
|
|
return 0; |
return 0; |
Line 553 static void* dlsym(const char* s) {
|
Line 561 static void* dlsym(const char* s) {
|
} |
} |
|
|
static void* _dlsym(const char* s) { |
static void* _dlsym(const char* s) { |
const void* x=dlsym(s); |
void* x=dlsym(s); |
if (!x) { |
if (!x) { |
__write2("ld.so: lookup of symbol \""); |
__write2("ld.so: lookup of symbol \""); |
__write2(s); |
__write2(s); |
Line 594 static void resolve(struct dll* D) {
|
Line 602 static void resolve(struct dll* D) {
|
|
|
for (i=0; i<rnum; ++i) { |
for (i=0; i<rnum; ++i) { |
size_t* x=(size_t*)((char*)(r[i].r_offset+D->codeplus)); |
size_t* x=(size_t*)((char*)(r[i].r_offset+D->codeplus)); |
|
char* y; |
size_t sym=R_SYM(r[i].r_info); |
size_t sym=R_SYM(r[i].r_info); |
switch (R_TYPE(r[i].r_info)) { |
switch (R_TYPE(r[i].r_info)) { |
#if defined(__x86_64__) |
#if defined(__x86_64__) |
Line 601 static void resolve(struct dll* D) {
|
Line 610 static void resolve(struct dll* D) {
|
*x=D->codeplus+symtab[sym].st_value; |
*x=D->codeplus+symtab[sym].st_value; |
break; |
break; |
case R_X86_64_COPY: |
case R_X86_64_COPY: |
_memcpy(x,dlsym_int(symtab[sym].st_name+dynstr,D->next),symtab[sym].st_size); |
y=dlsym_int(symtab[sym].st_name+dynstr,D->next); |
|
if (!y && ELF32_ST_BIND(symtab[sym].st_info) != STB_WEAK) { |
|
__write2("symbol lookup failed: "); |
|
__write2(dynstr+symtab[sym].st_name); |
|
__write2("\n"); |
|
exit(1); |
|
} |
|
_memcpy(x,y,symtab[sym].st_size); |
break; |
break; |
case R_X86_64_GLOB_DAT: |
case R_X86_64_GLOB_DAT: |
case R_X86_64_JUMP_SLOT: |
case R_X86_64_JUMP_SLOT: |
*x=(uintptr_t)_dlsym(symtab[sym].st_name+dynstr); |
y=dlsym(symtab[sym].st_name+dynstr); |
|
if (!y && ELF32_ST_BIND(symtab[sym].st_info) != STB_WEAK) { |
|
__write2("symbol lookup failed: "); |
|
__write2(dynstr+symtab[sym].st_name); |
|
__write2("\n"); |
|
exit(1); |
|
} |
|
*x=(uintptr_t)y; |
break; |
break; |
case R_X86_64_RELATIVE: |
case R_X86_64_RELATIVE: |
*x=r[i].r_addend+D->codeplus; |
*x=r[i].r_addend+D->codeplus; |
Line 756 kaputt:
|
Line 779 kaputt:
|
|
|
resolve(&dllroot); |
resolve(&dllroot); |
|
|
|
__write2("jumping...\n"); |
|
|
{ |
{ |
int (*_init)(int argc,char* argv[],char* envp[])=(void*)e->e_entry; |
int (*_init)(int argc,char* argv[],char* envp[])=(void*)(e->e_entry+dllroot.codeplus); |
return _init(argc,argv,envp); |
return _init(argc,argv,envp); |
} |
} |
#if 0 |
#if 0 |