OSDN Git Service

Yet more ldso cleanups. Be more discriminating about when using inlines
authorEric Andersen <andersen@codepoet.org>
Thu, 14 Jun 2001 21:37:48 +0000 (21:37 -0000)
committerEric Andersen <andersen@codepoet.org>
Thu, 14 Jun 2001 21:37:48 +0000 (21:37 -0000)
and when using real functions.  Make things be more portable by
providing a default C routine to locate the got.
 -Erik

23 files changed:
ldso/Makefile
ldso/Rules.mak [deleted file]
ldso/ldso/Makefile
ldso/ldso/boot1.c
ldso/ldso/hash.h
ldso/ldso/i386/dl-sysdep.h
ldso/ldso/i386/ld_sysdep.h
ldso/ldso/i386/sysdep.h
ldso/ldso/ld-uClibc.c
ldso/ldso/ld_hash.h
ldso/ldso/ld_string.h
ldso/ldso/ld_syscall.h
ldso/ldso/ldso.c
ldso/ldso/m68k/dl-sysdep.h
ldso/ldso/m68k/ld_sysdep.h
ldso/ldso/m68k/sysdep.h
ldso/ldso/sparc/dl-sysdep.h
ldso/ldso/sparc/ld_sysdep.h
ldso/ldso/sparc/sysdep.h
ldso/ldso/string.h
ldso/ldso/syscall.h
ldso/libdl/Makefile
ldso/util/Makefile

index 9fb609c..f26489e 100644 (file)
@@ -1,7 +1,8 @@
 TOPDIR=../
-include Rules.mak
+include $(TOPDIR)Rules.mak
 
-SUBDIRS = util libdl # d-link man
+SUBDIRS = util libdl
+ALL_SUBDIRS = util libdl d-link
 
 all:
        @if [ -d $(TOPDIR)ldso/d-link/$(TARGET_ARCH) ] ; then \
@@ -14,5 +15,5 @@ shared:
        fi;
 
 clean:
-       set -e ; for d in $(SUBDIRS) ; do $(MAKE) -C $$d $@ ; done
+       set -e ; for d in $(ALL_SUBDIRS) ; do $(MAKE) -C $$d $@ ; done
        -find . -name '*~' | xargs rm -f
diff --git a/ldso/Rules.mak b/ldso/Rules.mak
deleted file mode 100644 (file)
index b45e2df..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-include $(TOPDIR)Rules.mak
-
-# Do NOT use -fomit-frame-pointer -- It won't work!
-CFLAGS += -DUCLIBC_ROOT_DIR=\"$(ROOT_DIR)\"
-CC = $(TOPDIR)extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc
index d69823c..d9efabc 100644 (file)
@@ -22,7 +22,7 @@
 
 
 TOPDIR=../../
-include $(TOPDIR)/ldso/Rules.mak
+include $(TOPDIR)Rules.mak
 
 LDSO_FULLNAME=ld-uclibc-$(MAJOR_VERSION).$(MINOR_VERSION).so
 
@@ -34,7 +34,10 @@ AOBJS=$(patsubst %.S,%.o, $(ASRC))
 OBJS=$(AOBJS) $(COBJS)
 
 
-CFLAGS += -DUSE_CACHE -fPIC -D__PIC__ #-DDL_DEBUG #-funroll-loops
+CFLAGS=-Wall -Os -fPIC -D__PIC__ --uclibc-use-build-dir -I. -DUCLIBC_ROOT_DIR=\"$(ROOT_DIR)\"
+CC = $(TOPDIR)extra/gcc-uClibc/$(NATIVE_ARCH)-uclibc-gcc
+
+CFLAGS += #-DDL_DEBUG #-funroll-loops
 
 all: lib
 
@@ -45,8 +48,8 @@ lib:: ld.so.h $(OBJS) $(DLINK_OBJS)
        install -m 755 $(LDSO_FULLNAME) $(TOPDIR)lib; \
        (cd $(TOPDIR)lib;ln -sf $(LDSO_FULLNAME) $(UCLIBC_LDSO));
 
-ld.so.h:
-       echo "char *_dl_progname = \""$(UCLIBC_LDSO)"\";" > ld.so.h
+ld.so.h: Makefile
+       echo "#define _dl_static_progname \""$(UCLIBC_LDSO)"\"" > ld.so.h
 
 $(COBJS): %.o : %.c
        $(CC) -I. -I./$(TARGET_ARCH) -I../libdl $(CFLAGS) -c $< -o $@
index 52c9bcb..1da2b34 100644 (file)
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-#define ELF_HASH(RESULT,NAME) { \
-  unsigned long hash = 0; \
-    unsigned long tmp;  \
-  char * name = NAME; \
-  while (*name){  \
-    hash = (hash << 4) + *name++; \
-    if((tmp = hash & 0xf0000000)) hash ^= tmp >> 24; \
-    hash &= ~tmp; \
-  } \
-  RESULT = hash; \
-}
-
 static char *_dl_malloc_addr, *_dl_mmap_zero;
 char *_dl_library_path = 0;            /* Where we look for libraries */
 char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 #include "ld.so.h"                     /* Pull in the name of ld.so */
+const char *_dl_progname=_dl_static_progname;
 static char *_dl_not_lazy = 0;
 static char *_dl_warn = 0;             /* Used by ldd */
 static char *_dl_trace_loaded_objects = 0;
@@ -180,9 +169,14 @@ void _dl_boot(unsigned int args)
        int indx;
        int _dl_secure;
 
+
+       /* WARNING! -- we cannot make _any_ funtion calls until we have
+        * taken care of fixing up our own relocations.  Making static
+        * lnline calls is ok, but _no_ function calls.  Not yet
+        * anyways. */
+
        /* First obtain the information on the stack that tells us more about
           what binary is loaded, where it is loaded, etc, etc */
-
        GET_ARGV(aux_dat, args);
        argc = *(aux_dat - 1);
        argv = (char **) aux_dat;
@@ -193,7 +187,7 @@ void _dl_boot(unsigned int args)
                aux_dat++;                      /* Skip over the envp pointers */
        aux_dat++;                              /* Skip over NULL at end of envp */
 
-       /* Place -1 here as a checkpoint.  We check later to see if it got changed 
+       /* Place -1 here as a checkpoint.  We check later to see if it was changed 
         * when we read in the auxv_t */
        auxv_t[AT_UID].a_type = -1;
        
@@ -205,35 +199,92 @@ void _dl_boot(unsigned int args)
                Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
                if (auxv_entry->a_type <= AT_EGID) {
-                       _dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+                       _dl_memcpy_inline(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
                }
                aux_dat += 2;
        }
-
-       /* Next, locate the GOT */
+       
+       /* locate the ELF header.   We need this done as easly as possible 
+        * (esp since SEND_STDERR() needs this on some platforms... */
        load_addr = auxv_t[AT_BASE].a_un.a_val;
-       if (load_addr == 0x0) {
-           /* Looks like they decided to run ld-linux-uclibc.so as 
-            * an executable.  Exit gracefully for now. */
-
-           /* TODO -- actually accept executables and args to run... */
-           //SEND_STDERR("Usage: ld.so EXECUTABLE [ARGS...]\n");
-           SEND_STDERR("You have run `ld.so', the helper program for shared\n");
-           SEND_STDERR("library executables.  You probably did not intend to\n");
-           SEND_STDERR("run this as a program.  Goodbye.\n\n");
+       header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+       
+       /* check the ELF header to make sure everything looks ok.  */
+       if (! header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
+               header->e_ident[EI_VERSION] != EV_CURRENT || 
+               _dl_strncmp_inline((void *)header, ELFMAG, SELFMAG) != 0)
+       {
+           SEND_STDERR("invalid ELF header\n");
            _dl_exit(0);
        }
 #ifdef DL_DEBUG
-       SEND_STDERR("load_addr=");
+       SEND_STDERR("ELF header =");
        SEND_STDERR(_dl_simple_ltoahex(load_addr));
        SEND_STDERR("\n");
 #endif 
-       GET_GOT(got);
+
+
+       /* Locate the global offset table.  Since this code must be PIC  
+        * we can take advantage of the magic offset register, if we
+        * happen to know what that is for this architecture.  If not,
+        * we can always read stuff out of the ELF file to fine it... */
+#if defined(__i386__)
+       __asm__("\tmovl %%ebx,%0\n\t" : "=a" (got));
+#elif defined(__m68k__)
+       __asm__ ("movel %%a5,%0" : "=g" (got))
+#elif defined(__sparc__)
+       __asm__("\tmov %%l7,%0\n\t" : "=r" (got))
+#else
+       /* Do things the slow way in C */
+       {
+           unsigned long tx_reloc;
+           Elf32_Dyn *dynamic=NULL;
+           Elf32_Shdr *shdr;
+           Elf32_Phdr *pt_load;
+
 #ifdef DL_DEBUG
-       SEND_STDERR("Found got=");
-       SEND_STDERR(_dl_simple_ltoahex((unsigned long)*got));
-       SEND_STDERR("\n");
+           SEND_STDERR("Finding the got using C code to read the ELF file\n");
 #endif 
+           /* Find where the dynamic linking information section is hiding */
+           shdr = (Elf32_Shdr *)(header->e_shoff + (char *)header);
+           for (indx = header->e_shnum; --indx>=0; ++shdr) {
+               if (shdr->sh_type == SHT_DYNAMIC) {
+                   goto found_dynamic;
+               }
+           }
+           SEND_STDERR("missing dynamic linking information section \n");
+           _dl_exit(0);
+
+found_dynamic:
+           dynamic = (Elf32_Dyn*)(shdr->sh_offset + (char *)header);
+
+           /* Find where PT_LOAD is hiding */
+           pt_load = (Elf32_Phdr *)(header->e_phoff + (char *)header);
+           for (indx = header->e_phnum; --indx>=0; ++pt_load) {
+               if (pt_load->p_type == PT_LOAD) {
+                   goto found_pt_load;
+               }
+           }
+           SEND_STDERR("missing loadable program segment\n");
+           _dl_exit(0);
+
+found_pt_load:
+           /* Now (finally) find where DT_PLTGOT is hiding */
+           tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
+           for (; DT_NULL!=dynamic->d_tag; ++dynamic) {
+               if (dynamic->d_tag == DT_PLTGOT) {
+                   goto found_got;
+               }       
+           }       
+           SEND_STDERR("missing global offset table\n");
+           _dl_exit(0);
+
+found_got:
+           got = (unsigned long *)(dynamic->d_un.d_val - tx_reloc + (char *)header );
+       }
+#endif
+
+       /* Now, finally, fix up the location of the dynamic stuff */
        dpnt = (Elf32_Dyn *) (*got + load_addr);
 #ifdef DL_DEBUG
        SEND_STDERR("First Dynamic section entry=");
@@ -252,15 +303,15 @@ void _dl_boot(unsigned int args)
        }
 
        tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       _dl_memset_inline(tpnt, 0, sizeof(*tpnt));
        app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
+       _dl_memset_inline(app_tpnt, 0, sizeof(*app_tpnt));
 
        /*
         * This is used by gdb to locate the chain of shared libraries that are currently loaded.
         */
        debug_addr = DL_MALLOC(sizeof(struct r_debug));
-       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+       _dl_memset_inline(debug_addr, 0, sizeof(*debug_addr));
 
        /* OK, that was easy.  Next scan the DYNAMIC section of the image.
           We are only doing ourself right now - we will have to do the rest later */
@@ -1053,3 +1104,104 @@ char *_dl_get_last_path_component(char *path)
                return s+1;
 }
 
+size_t _dl_strlen(const char * str)
+{
+       register char *ptr = (char *) str;
+
+       while (*ptr)
+               ptr++;
+       return (ptr - str);
+}
+
+char * _dl_strcpy(char * dst,const char *src)
+{
+       register char *ptr = dst;
+
+       while (*src)
+               *dst++ = *src++;
+       *dst = '\0';
+
+       return ptr;
+}
+int _dl_strcmp(const char * s1,const char * s2)
+{
+       unsigned register char c1, c2;
+
+       do {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0')
+                       return c1 - c2;
+       }
+       while (c1 == c2);
+
+       return c1 - c2;
+}
+
+int _dl_strncmp(const char * s1,const char * s2,size_t len)
+{
+       unsigned register char c1 = '\0';
+       unsigned register char c2 = '\0';
+
+       while (len > 0) {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0' || c1 != c2)
+                       return c1 - c2;
+               len--;
+       }
+
+       return c1 - c2;
+}
+
+char * _dl_strchr(const char * str,int c)
+{
+       register char ch;
+
+       do {
+               if ((ch = *str) == c)
+                       return (char *) str;
+               str++;
+       }
+       while (ch);
+
+       return 0;
+}
+
+char *_dl_strrchr(const char *str, int c)
+{
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+       if (*ptr == c)
+           prev = ptr;
+       ptr++;  
+    }   
+    if (c == '\0')
+       return(ptr);
+    return(prev);
+}
+
+void * _dl_memcpy(void * dst, const void * src, size_t len)
+{
+       register char *a = dst;
+       register const char *b = src;
+
+       while (len--)
+               *a++ = *b++;
+
+       return dst;
+}
+
+void * _dl_memset(void * str,int c,size_t len)
+{
+       register char *a = str;
+
+       while (len--)
+               *a++ = c;
+
+       return str;
+}
+
index 74bac2f..cc1c56c 100644 (file)
@@ -77,25 +77,25 @@ extern int _dl_linux_dynamic_link(void);
 #define SEND_STDERR(X)                         \
   { const char *__s = (X);                     \
     if (__s < (const char *) load_addr) __s += load_addr;      \
-    _dl_write (2, __s, _dl_strlen (__s));      \
+    _dl_write (2, __s, _dl_strlen_inline (__s));       \
   }
 #else
-#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
+#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen_inline(X));
 #endif
 extern int _dl_fdprintf(int, const char *, ...);
 extern char * _dl_library_path;
 extern char * _dl_not_lazy;
 extern char * _dl_strdup(const char *);
-extern inline int _dl_symbol(char * name);
-unsigned long _dl_elf_hash(const char * name);
+extern unsigned long _dl_elf_hash(const char * name);
 
-extern inline int _dl_symbol(char * name)
+static inline int _dl_symbol(char * name)
 {
   if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
     return 0;
   return 1;
 }
 
+
 #define DL_ERROR_NOFILE 1
 #define DL_ERROR_NOZERO 2
 #define DL_ERROR_NOTELF 3
index 8e7fb65..d44b020 100644 (file)
  * do something a little more subtle here.
  */
 #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS)
-/*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmovl %%ebx,%0\n\t" : "=a" (X))
 
 /*
  * Initialization sequence for a GOT.
index 8e7fb65..d44b020 100644 (file)
  * do something a little more subtle here.
  */
 #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS)
-/*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmovl %%ebx,%0\n\t" : "=a" (X))
 
 /*
  * Initialization sequence for a GOT.
index 8e7fb65..d44b020 100644 (file)
  * do something a little more subtle here.
  */
 #define GET_ARGV(ARGVP, ARGS) ARGVP = ((unsigned long*) & ARGS)
-/*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmovl %%ebx,%0\n\t" : "=a" (X))
 
 /*
  * Initialization sequence for a GOT.
index 52c9bcb..1da2b34 100644 (file)
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-#define ELF_HASH(RESULT,NAME) { \
-  unsigned long hash = 0; \
-    unsigned long tmp;  \
-  char * name = NAME; \
-  while (*name){  \
-    hash = (hash << 4) + *name++; \
-    if((tmp = hash & 0xf0000000)) hash ^= tmp >> 24; \
-    hash &= ~tmp; \
-  } \
-  RESULT = hash; \
-}
-
 static char *_dl_malloc_addr, *_dl_mmap_zero;
 char *_dl_library_path = 0;            /* Where we look for libraries */
 char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 #include "ld.so.h"                     /* Pull in the name of ld.so */
+const char *_dl_progname=_dl_static_progname;
 static char *_dl_not_lazy = 0;
 static char *_dl_warn = 0;             /* Used by ldd */
 static char *_dl_trace_loaded_objects = 0;
@@ -180,9 +169,14 @@ void _dl_boot(unsigned int args)
        int indx;
        int _dl_secure;
 
+
+       /* WARNING! -- we cannot make _any_ funtion calls until we have
+        * taken care of fixing up our own relocations.  Making static
+        * lnline calls is ok, but _no_ function calls.  Not yet
+        * anyways. */
+
        /* First obtain the information on the stack that tells us more about
           what binary is loaded, where it is loaded, etc, etc */
-
        GET_ARGV(aux_dat, args);
        argc = *(aux_dat - 1);
        argv = (char **) aux_dat;
@@ -193,7 +187,7 @@ void _dl_boot(unsigned int args)
                aux_dat++;                      /* Skip over the envp pointers */
        aux_dat++;                              /* Skip over NULL at end of envp */
 
-       /* Place -1 here as a checkpoint.  We check later to see if it got changed 
+       /* Place -1 here as a checkpoint.  We check later to see if it was changed 
         * when we read in the auxv_t */
        auxv_t[AT_UID].a_type = -1;
        
@@ -205,35 +199,92 @@ void _dl_boot(unsigned int args)
                Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
                if (auxv_entry->a_type <= AT_EGID) {
-                       _dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+                       _dl_memcpy_inline(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
                }
                aux_dat += 2;
        }
-
-       /* Next, locate the GOT */
+       
+       /* locate the ELF header.   We need this done as easly as possible 
+        * (esp since SEND_STDERR() needs this on some platforms... */
        load_addr = auxv_t[AT_BASE].a_un.a_val;
-       if (load_addr == 0x0) {
-           /* Looks like they decided to run ld-linux-uclibc.so as 
-            * an executable.  Exit gracefully for now. */
-
-           /* TODO -- actually accept executables and args to run... */
-           //SEND_STDERR("Usage: ld.so EXECUTABLE [ARGS...]\n");
-           SEND_STDERR("You have run `ld.so', the helper program for shared\n");
-           SEND_STDERR("library executables.  You probably did not intend to\n");
-           SEND_STDERR("run this as a program.  Goodbye.\n\n");
+       header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+       
+       /* check the ELF header to make sure everything looks ok.  */
+       if (! header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
+               header->e_ident[EI_VERSION] != EV_CURRENT || 
+               _dl_strncmp_inline((void *)header, ELFMAG, SELFMAG) != 0)
+       {
+           SEND_STDERR("invalid ELF header\n");
            _dl_exit(0);
        }
 #ifdef DL_DEBUG
-       SEND_STDERR("load_addr=");
+       SEND_STDERR("ELF header =");
        SEND_STDERR(_dl_simple_ltoahex(load_addr));
        SEND_STDERR("\n");
 #endif 
-       GET_GOT(got);
+
+
+       /* Locate the global offset table.  Since this code must be PIC  
+        * we can take advantage of the magic offset register, if we
+        * happen to know what that is for this architecture.  If not,
+        * we can always read stuff out of the ELF file to fine it... */
+#if defined(__i386__)
+       __asm__("\tmovl %%ebx,%0\n\t" : "=a" (got));
+#elif defined(__m68k__)
+       __asm__ ("movel %%a5,%0" : "=g" (got))
+#elif defined(__sparc__)
+       __asm__("\tmov %%l7,%0\n\t" : "=r" (got))
+#else
+       /* Do things the slow way in C */
+       {
+           unsigned long tx_reloc;
+           Elf32_Dyn *dynamic=NULL;
+           Elf32_Shdr *shdr;
+           Elf32_Phdr *pt_load;
+
 #ifdef DL_DEBUG
-       SEND_STDERR("Found got=");
-       SEND_STDERR(_dl_simple_ltoahex((unsigned long)*got));
-       SEND_STDERR("\n");
+           SEND_STDERR("Finding the got using C code to read the ELF file\n");
 #endif 
+           /* Find where the dynamic linking information section is hiding */
+           shdr = (Elf32_Shdr *)(header->e_shoff + (char *)header);
+           for (indx = header->e_shnum; --indx>=0; ++shdr) {
+               if (shdr->sh_type == SHT_DYNAMIC) {
+                   goto found_dynamic;
+               }
+           }
+           SEND_STDERR("missing dynamic linking information section \n");
+           _dl_exit(0);
+
+found_dynamic:
+           dynamic = (Elf32_Dyn*)(shdr->sh_offset + (char *)header);
+
+           /* Find where PT_LOAD is hiding */
+           pt_load = (Elf32_Phdr *)(header->e_phoff + (char *)header);
+           for (indx = header->e_phnum; --indx>=0; ++pt_load) {
+               if (pt_load->p_type == PT_LOAD) {
+                   goto found_pt_load;
+               }
+           }
+           SEND_STDERR("missing loadable program segment\n");
+           _dl_exit(0);
+
+found_pt_load:
+           /* Now (finally) find where DT_PLTGOT is hiding */
+           tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
+           for (; DT_NULL!=dynamic->d_tag; ++dynamic) {
+               if (dynamic->d_tag == DT_PLTGOT) {
+                   goto found_got;
+               }       
+           }       
+           SEND_STDERR("missing global offset table\n");
+           _dl_exit(0);
+
+found_got:
+           got = (unsigned long *)(dynamic->d_un.d_val - tx_reloc + (char *)header );
+       }
+#endif
+
+       /* Now, finally, fix up the location of the dynamic stuff */
        dpnt = (Elf32_Dyn *) (*got + load_addr);
 #ifdef DL_DEBUG
        SEND_STDERR("First Dynamic section entry=");
@@ -252,15 +303,15 @@ void _dl_boot(unsigned int args)
        }
 
        tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       _dl_memset_inline(tpnt, 0, sizeof(*tpnt));
        app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
+       _dl_memset_inline(app_tpnt, 0, sizeof(*app_tpnt));
 
        /*
         * This is used by gdb to locate the chain of shared libraries that are currently loaded.
         */
        debug_addr = DL_MALLOC(sizeof(struct r_debug));
-       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+       _dl_memset_inline(debug_addr, 0, sizeof(*debug_addr));
 
        /* OK, that was easy.  Next scan the DYNAMIC section of the image.
           We are only doing ourself right now - we will have to do the rest later */
@@ -1053,3 +1104,104 @@ char *_dl_get_last_path_component(char *path)
                return s+1;
 }
 
+size_t _dl_strlen(const char * str)
+{
+       register char *ptr = (char *) str;
+
+       while (*ptr)
+               ptr++;
+       return (ptr - str);
+}
+
+char * _dl_strcpy(char * dst,const char *src)
+{
+       register char *ptr = dst;
+
+       while (*src)
+               *dst++ = *src++;
+       *dst = '\0';
+
+       return ptr;
+}
+int _dl_strcmp(const char * s1,const char * s2)
+{
+       unsigned register char c1, c2;
+
+       do {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0')
+                       return c1 - c2;
+       }
+       while (c1 == c2);
+
+       return c1 - c2;
+}
+
+int _dl_strncmp(const char * s1,const char * s2,size_t len)
+{
+       unsigned register char c1 = '\0';
+       unsigned register char c2 = '\0';
+
+       while (len > 0) {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0' || c1 != c2)
+                       return c1 - c2;
+               len--;
+       }
+
+       return c1 - c2;
+}
+
+char * _dl_strchr(const char * str,int c)
+{
+       register char ch;
+
+       do {
+               if ((ch = *str) == c)
+                       return (char *) str;
+               str++;
+       }
+       while (ch);
+
+       return 0;
+}
+
+char *_dl_strrchr(const char *str, int c)
+{
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+       if (*ptr == c)
+           prev = ptr;
+       ptr++;  
+    }   
+    if (c == '\0')
+       return(ptr);
+    return(prev);
+}
+
+void * _dl_memcpy(void * dst, const void * src, size_t len)
+{
+       register char *a = dst;
+       register const char *b = src;
+
+       while (len--)
+               *a++ = *b++;
+
+       return dst;
+}
+
+void * _dl_memset(void * str,int c,size_t len)
+{
+       register char *a = str;
+
+       while (len--)
+               *a++ = c;
+
+       return str;
+}
+
index 74bac2f..cc1c56c 100644 (file)
@@ -77,25 +77,25 @@ extern int _dl_linux_dynamic_link(void);
 #define SEND_STDERR(X)                         \
   { const char *__s = (X);                     \
     if (__s < (const char *) load_addr) __s += load_addr;      \
-    _dl_write (2, __s, _dl_strlen (__s));      \
+    _dl_write (2, __s, _dl_strlen_inline (__s));       \
   }
 #else
-#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen(X));
+#define SEND_STDERR(X) _dl_write(2, X, _dl_strlen_inline(X));
 #endif
 extern int _dl_fdprintf(int, const char *, ...);
 extern char * _dl_library_path;
 extern char * _dl_not_lazy;
 extern char * _dl_strdup(const char *);
-extern inline int _dl_symbol(char * name);
-unsigned long _dl_elf_hash(const char * name);
+extern unsigned long _dl_elf_hash(const char * name);
 
-extern inline int _dl_symbol(char * name)
+static inline int _dl_symbol(char * name)
 {
   if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
     return 0;
   return 1;
 }
 
+
 #define DL_ERROR_NOFILE 1
 #define DL_ERROR_NOZERO 2
 #define DL_ERROR_NOTELF 3
index 5e912ea..4a34626 100644 (file)
@@ -3,11 +3,26 @@
 
 #include <sys/types.h> /* for size_t */
 
+extern void *_dl_malloc(int size);
+extern char *_dl_getenv(char *symbol, char **envp);
+extern void _dl_unsetenv(char *symbol, char **envp);
+extern char *_dl_strdup(const char *string);
+extern char *_dl_get_last_path_component(char *path);
+extern size_t _dl_strlen(const char * str);
+extern char * _dl_strcpy(char * dst,const char *src);
+extern int _dl_strcmp(const char * s1,const char * s2);
+extern int _dl_strncmp(const char * s1,const char * s2,size_t len);
+extern char * _dl_strchr(const char * str,int c);
+extern char *_dl_strrchr(const char *str, int c);
+extern void * _dl_memcpy(void * dst, const void * src, size_t len);
+extern int _dl_memcmp(const void * s1,const void * s2,size_t len);
+extern void * _dl_memset(void * str,int c,size_t len);
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
 
-extern inline size_t _dl_strlen(const char * str)
+static inline size_t _dl_strlen_inline(const char * str)
 {
        register char *ptr = (char *) str;
 
@@ -16,7 +31,7 @@ extern inline size_t _dl_strlen(const char * str)
        return (ptr - str);
 }
 
-extern inline char * _dl_strcpy(char * dst,const char *src)
+static inline char * _dl_strcpy_inline(char * dst,const char *src)
 {
        register char *ptr = dst;
 
@@ -27,7 +42,7 @@ extern inline char * _dl_strcpy(char * dst,const char *src)
        return ptr;
 }
  
-extern inline int _dl_strcmp(const char * s1,const char * s2)
+static inline int _dl_strcmp_inline(const char * s1,const char * s2)
 {
        unsigned register char c1, c2;
 
@@ -42,7 +57,7 @@ extern inline int _dl_strcmp(const char * s1,const char * s2)
        return c1 - c2;
 }
 
-extern inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
+static inline int _dl_strncmp_inline(const char * s1,const char * s2,size_t len)
 {
        unsigned register char c1 = '\0';
        unsigned register char c2 = '\0';
@@ -58,7 +73,7 @@ extern inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
        return c1 - c2;
 }
 
-extern inline char * _dl_strchr(const char * str,int c)
+static inline char * _dl_strchr_inline(const char * str,int c)
 {
        register char ch;
 
@@ -72,25 +87,22 @@ extern inline char * _dl_strchr(const char * str,int c)
        return 0;
 }
 
-static inline char *_dl_strrchr(const char *str, int c)
+static inline char *_dl_strrchr_inline(const char *str, int c)
 {
-       register char *prev = 0;
-       register char *ptr = (char *) str;
-
-       /* For null it's just like strlen */
-       if (c == '\0') {
-               return ptr + _dl_strlen(ptr);
-       }
-
-       /* everything else just step along the string. */
-       while ((ptr = _dl_strchr(ptr, c)) != 0) {
-               prev = ptr;
-               ptr++;
-       }
-       return prev;
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+       if (*ptr == c)
+           prev = ptr;
+       ptr++;  
+    }   
+    if (c == '\0')
+       return(ptr);
+    return(prev);
 }
 
-extern inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+static inline void * _dl_memcpy_inline(void * dst, const void * src, size_t len)
 {
        register char *a = dst;
        register const char *b = src;
@@ -102,7 +114,7 @@ extern inline void * _dl_memcpy(void * dst, const void * src, size_t len)
 }
 
 
-extern inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
+static inline int _dl_memcmp_inline(const void * s1,const void * s2,size_t len)
 {
        unsigned char *c1 = (unsigned char *)s1;
        unsigned char *c2 = (unsigned char *)s2;
@@ -116,7 +128,7 @@ extern inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
        return 0;
 }
 
-extern inline void * _dl_memset(void * str,int c,size_t len)
+static inline void * _dl_memset_inline(void * str,int c,size_t len)
 {
        register char *a = str;
 
@@ -126,9 +138,39 @@ extern inline void * _dl_memset(void * str,int c,size_t len)
        return str;
 }
 
+static inline char *_dl_get_last_path_component_inline(char *path)
+{
+       char *s;
+       register char *ptr = path;
+       register char *prev = 0;
+
+       while (*ptr)
+               ptr++;
+       s = ptr - 1;
+
+       /* strip trailing slashes */
+       while (s != path && *s == '/') {
+               *s-- = '\0';
+       }
+
+       /* find last component */
+       ptr = path;
+       while (*ptr != '\0') {
+           if (*ptr == '/')
+               prev = ptr;
+           ptr++;  
+       }   
+       s = prev;
+
+       if (s == NULL || s[1] == '\0')
+               return path;
+       else
+               return s+1;
+}
+
 /* Early on, we can't call printf, so use this to print out
  * numbers using the SEND_STDERR() macro */
-static inline char *_dl_simple_ltoa(unsigned long i)
+static inline char *_dl_simple_ltoa_inline(unsigned long i)
 {
        /* 21 digits plus null terminator, good for 64-bit or smaller ints */
        static char local[22];
index ebc8739..28c002c 100644 (file)
@@ -99,7 +99,7 @@ static inline _syscall0(gid_t, _dl_getegid);
  * Not an actual syscall, but we need something in assembly to say whether
  * this is OK or not.
  */
-extern inline int _dl_suid_ok(void)
+static inline int _dl_suid_ok(void)
 {
     uid_t uid, euid, gid, egid;
 
index 52c9bcb..1da2b34 100644 (file)
  */
 #define REALIGN() malloc_buffer = (char *) (((unsigned long) malloc_buffer + 3) & ~(3))
 
-#define ELF_HASH(RESULT,NAME) { \
-  unsigned long hash = 0; \
-    unsigned long tmp;  \
-  char * name = NAME; \
-  while (*name){  \
-    hash = (hash << 4) + *name++; \
-    if((tmp = hash & 0xf0000000)) hash ^= tmp >> 24; \
-    hash &= ~tmp; \
-  } \
-  RESULT = hash; \
-}
-
 static char *_dl_malloc_addr, *_dl_mmap_zero;
 char *_dl_library_path = 0;            /* Where we look for libraries */
 char *_dl_preload = 0;                 /* Things to be loaded before the libs. */
 #include "ld.so.h"                     /* Pull in the name of ld.so */
+const char *_dl_progname=_dl_static_progname;
 static char *_dl_not_lazy = 0;
 static char *_dl_warn = 0;             /* Used by ldd */
 static char *_dl_trace_loaded_objects = 0;
@@ -180,9 +169,14 @@ void _dl_boot(unsigned int args)
        int indx;
        int _dl_secure;
 
+
+       /* WARNING! -- we cannot make _any_ funtion calls until we have
+        * taken care of fixing up our own relocations.  Making static
+        * lnline calls is ok, but _no_ function calls.  Not yet
+        * anyways. */
+
        /* First obtain the information on the stack that tells us more about
           what binary is loaded, where it is loaded, etc, etc */
-
        GET_ARGV(aux_dat, args);
        argc = *(aux_dat - 1);
        argv = (char **) aux_dat;
@@ -193,7 +187,7 @@ void _dl_boot(unsigned int args)
                aux_dat++;                      /* Skip over the envp pointers */
        aux_dat++;                              /* Skip over NULL at end of envp */
 
-       /* Place -1 here as a checkpoint.  We check later to see if it got changed 
+       /* Place -1 here as a checkpoint.  We check later to see if it was changed 
         * when we read in the auxv_t */
        auxv_t[AT_UID].a_type = -1;
        
@@ -205,35 +199,92 @@ void _dl_boot(unsigned int args)
                Elf32_auxv_t *auxv_entry = (Elf32_auxv_t*) aux_dat;
 
                if (auxv_entry->a_type <= AT_EGID) {
-                       _dl_memcpy(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+                       _dl_memcpy_inline(&(auxv_t[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
                }
                aux_dat += 2;
        }
-
-       /* Next, locate the GOT */
+       
+       /* locate the ELF header.   We need this done as easly as possible 
+        * (esp since SEND_STDERR() needs this on some platforms... */
        load_addr = auxv_t[AT_BASE].a_un.a_val;
-       if (load_addr == 0x0) {
-           /* Looks like they decided to run ld-linux-uclibc.so as 
-            * an executable.  Exit gracefully for now. */
-
-           /* TODO -- actually accept executables and args to run... */
-           //SEND_STDERR("Usage: ld.so EXECUTABLE [ARGS...]\n");
-           SEND_STDERR("You have run `ld.so', the helper program for shared\n");
-           SEND_STDERR("library executables.  You probably did not intend to\n");
-           SEND_STDERR("run this as a program.  Goodbye.\n\n");
+       header = (elfhdr *) auxv_t[AT_BASE].a_un.a_ptr;
+       
+       /* check the ELF header to make sure everything looks ok.  */
+       if (! header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
+               header->e_ident[EI_VERSION] != EV_CURRENT || 
+               _dl_strncmp_inline((void *)header, ELFMAG, SELFMAG) != 0)
+       {
+           SEND_STDERR("invalid ELF header\n");
            _dl_exit(0);
        }
 #ifdef DL_DEBUG
-       SEND_STDERR("load_addr=");
+       SEND_STDERR("ELF header =");
        SEND_STDERR(_dl_simple_ltoahex(load_addr));
        SEND_STDERR("\n");
 #endif 
-       GET_GOT(got);
+
+
+       /* Locate the global offset table.  Since this code must be PIC  
+        * we can take advantage of the magic offset register, if we
+        * happen to know what that is for this architecture.  If not,
+        * we can always read stuff out of the ELF file to fine it... */
+#if defined(__i386__)
+       __asm__("\tmovl %%ebx,%0\n\t" : "=a" (got));
+#elif defined(__m68k__)
+       __asm__ ("movel %%a5,%0" : "=g" (got))
+#elif defined(__sparc__)
+       __asm__("\tmov %%l7,%0\n\t" : "=r" (got))
+#else
+       /* Do things the slow way in C */
+       {
+           unsigned long tx_reloc;
+           Elf32_Dyn *dynamic=NULL;
+           Elf32_Shdr *shdr;
+           Elf32_Phdr *pt_load;
+
 #ifdef DL_DEBUG
-       SEND_STDERR("Found got=");
-       SEND_STDERR(_dl_simple_ltoahex((unsigned long)*got));
-       SEND_STDERR("\n");
+           SEND_STDERR("Finding the got using C code to read the ELF file\n");
 #endif 
+           /* Find where the dynamic linking information section is hiding */
+           shdr = (Elf32_Shdr *)(header->e_shoff + (char *)header);
+           for (indx = header->e_shnum; --indx>=0; ++shdr) {
+               if (shdr->sh_type == SHT_DYNAMIC) {
+                   goto found_dynamic;
+               }
+           }
+           SEND_STDERR("missing dynamic linking information section \n");
+           _dl_exit(0);
+
+found_dynamic:
+           dynamic = (Elf32_Dyn*)(shdr->sh_offset + (char *)header);
+
+           /* Find where PT_LOAD is hiding */
+           pt_load = (Elf32_Phdr *)(header->e_phoff + (char *)header);
+           for (indx = header->e_phnum; --indx>=0; ++pt_load) {
+               if (pt_load->p_type == PT_LOAD) {
+                   goto found_pt_load;
+               }
+           }
+           SEND_STDERR("missing loadable program segment\n");
+           _dl_exit(0);
+
+found_pt_load:
+           /* Now (finally) find where DT_PLTGOT is hiding */
+           tx_reloc = pt_load->p_vaddr - pt_load->p_offset;
+           for (; DT_NULL!=dynamic->d_tag; ++dynamic) {
+               if (dynamic->d_tag == DT_PLTGOT) {
+                   goto found_got;
+               }       
+           }       
+           SEND_STDERR("missing global offset table\n");
+           _dl_exit(0);
+
+found_got:
+           got = (unsigned long *)(dynamic->d_un.d_val - tx_reloc + (char *)header );
+       }
+#endif
+
+       /* Now, finally, fix up the location of the dynamic stuff */
        dpnt = (Elf32_Dyn *) (*got + load_addr);
 #ifdef DL_DEBUG
        SEND_STDERR("First Dynamic section entry=");
@@ -252,15 +303,15 @@ void _dl_boot(unsigned int args)
        }
 
        tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(tpnt, 0, sizeof(*tpnt));
+       _dl_memset_inline(tpnt, 0, sizeof(*tpnt));
        app_tpnt = DL_MALLOC(sizeof(struct elf_resolve));
-       _dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
+       _dl_memset_inline(app_tpnt, 0, sizeof(*app_tpnt));
 
        /*
         * This is used by gdb to locate the chain of shared libraries that are currently loaded.
         */
        debug_addr = DL_MALLOC(sizeof(struct r_debug));
-       _dl_memset(debug_addr, 0, sizeof(*debug_addr));
+       _dl_memset_inline(debug_addr, 0, sizeof(*debug_addr));
 
        /* OK, that was easy.  Next scan the DYNAMIC section of the image.
           We are only doing ourself right now - we will have to do the rest later */
@@ -1053,3 +1104,104 @@ char *_dl_get_last_path_component(char *path)
                return s+1;
 }
 
+size_t _dl_strlen(const char * str)
+{
+       register char *ptr = (char *) str;
+
+       while (*ptr)
+               ptr++;
+       return (ptr - str);
+}
+
+char * _dl_strcpy(char * dst,const char *src)
+{
+       register char *ptr = dst;
+
+       while (*src)
+               *dst++ = *src++;
+       *dst = '\0';
+
+       return ptr;
+}
+int _dl_strcmp(const char * s1,const char * s2)
+{
+       unsigned register char c1, c2;
+
+       do {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0')
+                       return c1 - c2;
+       }
+       while (c1 == c2);
+
+       return c1 - c2;
+}
+
+int _dl_strncmp(const char * s1,const char * s2,size_t len)
+{
+       unsigned register char c1 = '\0';
+       unsigned register char c2 = '\0';
+
+       while (len > 0) {
+               c1 = (unsigned char) *s1++;
+               c2 = (unsigned char) *s2++;
+               if (c1 == '\0' || c1 != c2)
+                       return c1 - c2;
+               len--;
+       }
+
+       return c1 - c2;
+}
+
+char * _dl_strchr(const char * str,int c)
+{
+       register char ch;
+
+       do {
+               if ((ch = *str) == c)
+                       return (char *) str;
+               str++;
+       }
+       while (ch);
+
+       return 0;
+}
+
+char *_dl_strrchr(const char *str, int c)
+{
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+       if (*ptr == c)
+           prev = ptr;
+       ptr++;  
+    }   
+    if (c == '\0')
+       return(ptr);
+    return(prev);
+}
+
+void * _dl_memcpy(void * dst, const void * src, size_t len)
+{
+       register char *a = dst;
+       register const char *b = src;
+
+       while (len--)
+               *a++ = *b++;
+
+       return dst;
+}
+
+void * _dl_memset(void * str,int c,size_t len)
+{
+       register char *a = str;
+
+       while (len--)
+               *a++ = c;
+
+       return str;
+}
+
index 24af47c..a908928 100644 (file)
    to do something a little more subtle here.  */
 #define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS)))
 
-/* Get the address of the Global offset table.  This must be absolute,
-   not relative.  */
-#define GET_GOT(X)     __asm__ ("movel %%a5,%0" : "=g" (X))
-
 /* Initialization sequence for a GOT.  */
 #define INIT_GOT(GOT_BASE,MODULE)              \
 {                                              \
index 24af47c..a908928 100644 (file)
    to do something a little more subtle here.  */
 #define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS)))
 
-/* Get the address of the Global offset table.  This must be absolute,
-   not relative.  */
-#define GET_GOT(X)     __asm__ ("movel %%a5,%0" : "=g" (X))
-
 /* Initialization sequence for a GOT.  */
 #define INIT_GOT(GOT_BASE,MODULE)              \
 {                                              \
index 24af47c..a908928 100644 (file)
    to do something a little more subtle here.  */
 #define GET_ARGV(ARGVP, ARGS) ((ARGVP) = ((unsigned int *) &(ARGS)))
 
-/* Get the address of the Global offset table.  This must be absolute,
-   not relative.  */
-#define GET_GOT(X)     __asm__ ("movel %%a5,%0" : "=g" (X))
-
 /* Initialization sequence for a GOT.  */
 #define INIT_GOT(GOT_BASE,MODULE)              \
 {                                              \
index 1d4c035..3c8d9b8 100644 (file)
 #define ELF_USES_RELOCA
 
 /*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmov %%l7,%0\n\t" : "=r" (X))
-
-/*
  * Get a pointer to the argv array.  On many platforms this can be just
  * the address if the first argument, on other platforms we need to
  * do something a little more subtle here.  We assume that argc is stored
index 1d4c035..3c8d9b8 100644 (file)
 #define ELF_USES_RELOCA
 
 /*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmov %%l7,%0\n\t" : "=r" (X))
-
-/*
  * Get a pointer to the argv array.  On many platforms this can be just
  * the address if the first argument, on other platforms we need to
  * do something a little more subtle here.  We assume that argc is stored
index 1d4c035..3c8d9b8 100644 (file)
 #define ELF_USES_RELOCA
 
 /*
- * Get the address of the Global offset table.  This must be absolute, not
- * relative.
- */
-#define GET_GOT(X)     __asm__("\tmov %%l7,%0\n\t" : "=r" (X))
-
-/*
  * Get a pointer to the argv array.  On many platforms this can be just
  * the address if the first argument, on other platforms we need to
  * do something a little more subtle here.  We assume that argc is stored
index 5e912ea..4a34626 100644 (file)
@@ -3,11 +3,26 @@
 
 #include <sys/types.h> /* for size_t */
 
+extern void *_dl_malloc(int size);
+extern char *_dl_getenv(char *symbol, char **envp);
+extern void _dl_unsetenv(char *symbol, char **envp);
+extern char *_dl_strdup(const char *string);
+extern char *_dl_get_last_path_component(char *path);
+extern size_t _dl_strlen(const char * str);
+extern char * _dl_strcpy(char * dst,const char *src);
+extern int _dl_strcmp(const char * s1,const char * s2);
+extern int _dl_strncmp(const char * s1,const char * s2,size_t len);
+extern char * _dl_strchr(const char * str,int c);
+extern char *_dl_strrchr(const char *str, int c);
+extern void * _dl_memcpy(void * dst, const void * src, size_t len);
+extern int _dl_memcmp(const void * s1,const void * s2,size_t len);
+extern void * _dl_memset(void * str,int c,size_t len);
+
 #ifndef NULL
 #define NULL ((void *) 0)
 #endif
 
-extern inline size_t _dl_strlen(const char * str)
+static inline size_t _dl_strlen_inline(const char * str)
 {
        register char *ptr = (char *) str;
 
@@ -16,7 +31,7 @@ extern inline size_t _dl_strlen(const char * str)
        return (ptr - str);
 }
 
-extern inline char * _dl_strcpy(char * dst,const char *src)
+static inline char * _dl_strcpy_inline(char * dst,const char *src)
 {
        register char *ptr = dst;
 
@@ -27,7 +42,7 @@ extern inline char * _dl_strcpy(char * dst,const char *src)
        return ptr;
 }
  
-extern inline int _dl_strcmp(const char * s1,const char * s2)
+static inline int _dl_strcmp_inline(const char * s1,const char * s2)
 {
        unsigned register char c1, c2;
 
@@ -42,7 +57,7 @@ extern inline int _dl_strcmp(const char * s1,const char * s2)
        return c1 - c2;
 }
 
-extern inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
+static inline int _dl_strncmp_inline(const char * s1,const char * s2,size_t len)
 {
        unsigned register char c1 = '\0';
        unsigned register char c2 = '\0';
@@ -58,7 +73,7 @@ extern inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
        return c1 - c2;
 }
 
-extern inline char * _dl_strchr(const char * str,int c)
+static inline char * _dl_strchr_inline(const char * str,int c)
 {
        register char ch;
 
@@ -72,25 +87,22 @@ extern inline char * _dl_strchr(const char * str,int c)
        return 0;
 }
 
-static inline char *_dl_strrchr(const char *str, int c)
+static inline char *_dl_strrchr_inline(const char *str, int c)
 {
-       register char *prev = 0;
-       register char *ptr = (char *) str;
-
-       /* For null it's just like strlen */
-       if (c == '\0') {
-               return ptr + _dl_strlen(ptr);
-       }
-
-       /* everything else just step along the string. */
-       while ((ptr = _dl_strchr(ptr, c)) != 0) {
-               prev = ptr;
-               ptr++;
-       }
-       return prev;
+    register char *prev = 0;
+    register char *ptr = (char *) str;
+
+    while (*ptr != '\0') {
+       if (*ptr == c)
+           prev = ptr;
+       ptr++;  
+    }   
+    if (c == '\0')
+       return(ptr);
+    return(prev);
 }
 
-extern inline void * _dl_memcpy(void * dst, const void * src, size_t len)
+static inline void * _dl_memcpy_inline(void * dst, const void * src, size_t len)
 {
        register char *a = dst;
        register const char *b = src;
@@ -102,7 +114,7 @@ extern inline void * _dl_memcpy(void * dst, const void * src, size_t len)
 }
 
 
-extern inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
+static inline int _dl_memcmp_inline(const void * s1,const void * s2,size_t len)
 {
        unsigned char *c1 = (unsigned char *)s1;
        unsigned char *c2 = (unsigned char *)s2;
@@ -116,7 +128,7 @@ extern inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
        return 0;
 }
 
-extern inline void * _dl_memset(void * str,int c,size_t len)
+static inline void * _dl_memset_inline(void * str,int c,size_t len)
 {
        register char *a = str;
 
@@ -126,9 +138,39 @@ extern inline void * _dl_memset(void * str,int c,size_t len)
        return str;
 }
 
+static inline char *_dl_get_last_path_component_inline(char *path)
+{
+       char *s;
+       register char *ptr = path;
+       register char *prev = 0;
+
+       while (*ptr)
+               ptr++;
+       s = ptr - 1;
+
+       /* strip trailing slashes */
+       while (s != path && *s == '/') {
+               *s-- = '\0';
+       }
+
+       /* find last component */
+       ptr = path;
+       while (*ptr != '\0') {
+           if (*ptr == '/')
+               prev = ptr;
+           ptr++;  
+       }   
+       s = prev;
+
+       if (s == NULL || s[1] == '\0')
+               return path;
+       else
+               return s+1;
+}
+
 /* Early on, we can't call printf, so use this to print out
  * numbers using the SEND_STDERR() macro */
-static inline char *_dl_simple_ltoa(unsigned long i)
+static inline char *_dl_simple_ltoa_inline(unsigned long i)
 {
        /* 21 digits plus null terminator, good for 64-bit or smaller ints */
        static char local[22];
index ebc8739..28c002c 100644 (file)
@@ -99,7 +99,7 @@ static inline _syscall0(gid_t, _dl_getegid);
  * Not an actual syscall, but we need something in assembly to say whether
  * this is OK or not.
  */
-extern inline int _dl_suid_ok(void)
+static inline int _dl_suid_ok(void)
 {
     uid_t uid, euid, gid, egid;
 
index 7d5f27d..f520272 100644 (file)
@@ -22,7 +22,7 @@
 
 
 TOPDIR=../../
-include $(TOPDIR)/ldso/Rules.mak
+include $(TOPDIR)Rules.mak
 
 LIBDL=libdl.a
 LIBDL_SHARED=libdl.so
@@ -32,7 +32,7 @@ TARGET_CC= $(TOPDIR)extra/gcc-uClibc/$(TARGET_ARCH)-uclibc-gcc
 CSRC= dlib.c
 OBJS=$(patsubst %.c,%.o, $(CSRC))
 
-CFLAGS += -DUSE_CACHE #-fPIC -D__PIC__ #-funroll-loops
+CFLAGS += --uclibc-use-build-dir -DUSE_CACHE #-fPIC -D__PIC__ #-funroll-loops
 
 all: $(OBJS) $(LIBDL) shared
 
index 725fc9b..f2486fd 100644 (file)
@@ -1,7 +1,7 @@
 TOPDIR=../../
 include $(TOPDIR)Rules.mak
 
-CFLAGS=-Wall -Os -I- -I. --uclibc-use-build-dir
+CFLAGS=-Wall -Os -I. --uclibc-use-build-dir
 CC = $(TOPDIR)extra/gcc-uClibc/$(NATIVE_ARCH)-uclibc-gcc
 
 all: ldconfig ldd readelf