Diff for /dietlibc/ldso.c between versions 1.2 and 1.3

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

Removed from v.1.2  
changed lines
  Added in v.1.3


LinuxTV legacy CVS <linuxtv.org/cvs>