"impossible asm" compiles if I do not optimize

Adam J. Richter adam@yggdrasil.com
Sun Dec 7 14:58:00 GMT 1997


	The "old" Linux dynamic loader FTPable from sunsite.unc.edu
 has a file that does not compile with optimization on Linux + glibc2:

d-link/boot1.c:
gcc -Wall -O4 -g -DVERSION=\"1.9.5\" -D_GNU_SOURCE -I. -I./i386 -DNO_UNDERSCORE -DVERBOSE_DLINKER -DUSE_CACHE -fPIC -D__PIC__    -c boot1.c -o boot1.o
In file included from boot1.c:109:
linuxelf.h:95: warning: type defaults to `int' in declaration of `_dl_linux_resolve'
boot1.c:157: warning: type defaults to `int' in declaration of `_dl_linux_resolve'
boot1.c: In function `_dl_boot':
boot1.c:243: warning: `zfileno' might be used uninitialized in this function
boot1.c:897: fixed or forbidden register was spilled.
This may be due to a compiler bug or to impossible asm
statements or clauses.

This problem occurs with -O4, -O3, -O2, -O1, but not -O0.  I looked at
the asm that is confusing egcs, but I really don't know enough
about the x86 machine description to know if the is a problem with
the asm statement.  However, the file compiles file without optimization,
so this suggests a compiler bug to me.  Anyhow, I have attached 
the C preprocessor output.  I hope this helps.

By the way, before anybody asks me about this, let me mention that I
know that most of the functionality of ld.so-1.9.5.tar.gz has been
supplanted by the dynamic loader included with glibc-2.0.5; however,
I believe that ld.so-1.9.5 is still necessary for supporting dynamic
"a.out" format executables.

Adam J. Richter     __     ______________   4880 Stevens Creek Blvd, Suite 205
adam@yggdrasil.com     \ /                  San Jose, California 95129-1034
+1 408 261-6630         | g g d r a s i l   United States of America
fax +1 408 261-6631      "Free Software For The Rest Of Us."

-------------------------------CUT HERE-----------------------------------

# 1 "boot1.c"
 



















 



 






 






























































# 1 "/usr/lib/gcc-lib/i686-pc-linux-gnu/pgcc-2.90.21/include/stdarg.h" 1 3
 





























































 






typedef void *__gnuc_va_list;



 



 














void va_end (__gnuc_va_list);		 


 



 












 






















 
 













# 168 "/usr/lib/gcc-lib/i686-pc-linux-gnu/pgcc-2.90.21/include/stdarg.h" 3


 




 

 

 

typedef __gnuc_va_list va_list;
























# 95 "boot1.c" 2

# 1 "/usr/include/linux/types.h" 1 3



# 1 "/usr/include/linux/posix_types.h" 1 3



 









 










 


















typedef struct {
	unsigned long fds_bits [(1024 / (8 * sizeof(unsigned long)) ) ];
} __kernel_fd_set;

# 1 "/usr/include/asm/posix_types.h" 1 3



 





typedef unsigned short	__kernel_dev_t;
typedef unsigned long	__kernel_ino_t;
typedef unsigned short	__kernel_mode_t;
typedef unsigned short	__kernel_nlink_t;
typedef long		__kernel_off_t;
typedef int		__kernel_pid_t;
typedef unsigned short	__kernel_uid_t;
typedef unsigned short	__kernel_gid_t;
typedef unsigned int	__kernel_size_t;
typedef int		__kernel_ssize_t;
typedef int		__kernel_ptrdiff_t;
typedef long		__kernel_time_t;
typedef long		__kernel_clock_t;
typedef int		__kernel_daddr_t;
typedef char *		__kernel_caddr_t;


typedef long long	__kernel_loff_t;


typedef struct {



	int	__val[2];

} __kernel_fsid_t;



























# 48 "/usr/include/linux/posix_types.h" 2 3



# 4 "/usr/include/linux/types.h" 2 3

# 1 "/usr/include/asm/types.h" 1 3



typedef unsigned short umode_t;

 




typedef __signed__ char __s8;
typedef unsigned char __u8;

typedef __signed__ short __s16;
typedef unsigned short __u16;

typedef __signed__ int __s32;
typedef unsigned int __u32;


typedef __signed__ long long __s64;
typedef unsigned long long __u64;


 


# 42 "/usr/include/asm/types.h" 3



# 5 "/usr/include/linux/types.h" 2 3




typedef __kernel_fd_set		fd_set;
typedef __kernel_dev_t		dev_t;
typedef __kernel_ino_t		ino_t;
typedef __kernel_mode_t		mode_t;
typedef __kernel_nlink_t	nlink_t;
typedef __kernel_off_t		off_t;
typedef __kernel_pid_t		pid_t;
typedef __kernel_uid_t		uid_t;
typedef __kernel_gid_t		gid_t;
typedef __kernel_daddr_t	daddr_t;


typedef __kernel_loff_t		loff_t;


 





typedef __kernel_size_t		size_t;




typedef __kernel_ssize_t	ssize_t;




typedef __kernel_ptrdiff_t	ptrdiff_t;




typedef __kernel_time_t		time_t;




typedef __kernel_clock_t	clock_t;




typedef __kernel_caddr_t	caddr_t;


 
typedef unsigned char		u_char;
typedef unsigned short		u_short;
typedef unsigned int		u_int;
typedef unsigned long		u_long;

 
typedef unsigned char		unchar;
typedef unsigned short		ushort;
typedef unsigned int		uint;
typedef unsigned long		ulong;



 




struct ustat {
	__kernel_daddr_t	f_tfree;
	__kernel_ino_t		f_tinode;
	char			f_fname[6];
	char			f_fpack[6];
};


# 96 "boot1.c" 2

# 1 "/usr/include/linux/fcntl.h" 1 3



# 1 "/usr/include/asm/fcntl.h" 1 3




# 1 "/usr/include/linux/linux_vs_ibcs.h" 1 3











# 5 "/usr/include/asm/fcntl.h" 2 3


 











# 27 "/usr/include/asm/fcntl.h" 3
























 


 




 



 






struct flock {
	short l_type;
	short l_whence;
	off_t l_start;
	off_t l_len;
	pid_t l_pid;



};


# 4 "/usr/include/linux/fcntl.h" 2 3



# 97 "boot1.c" 2




# 1 "/usr/include/linux/unistd.h" 1 3



extern int errno;

 


# 1 "/usr/include/asm/unistd.h" 1 3



 








































































































































































 

# 186 "/usr/include/asm/unistd.h" 3


# 199 "/usr/include/asm/unistd.h" 3


# 212 "/usr/include/asm/unistd.h" 3


# 226 "/usr/include/asm/unistd.h" 3


# 240 "/usr/include/asm/unistd.h" 3


# 255 "/usr/include/asm/unistd.h" 3

# 321 "/usr/include/asm/unistd.h" 3



# 9 "/usr/include/linux/unistd.h" 2 3



# 101 "boot1.c" 2


# 1 "/usr/include/linux/elf.h" 1 3



# 1 "/usr/include/asm/elf.h" 1 3



 



# 1 "/usr/include/asm/ptrace.h" 1 3






















 


struct pt_regs {
	long ebx;
	long ecx;
	long edx;
	long esi;
	long edi;
	long ebp;
	long eax;
	unsigned short ds, __dsu;
	unsigned short es, __esu;
	unsigned short fs, __fsu;
	unsigned short gs, __gsu;
	long orig_eax;
	long eip;
	unsigned short cs, __csu;
	long eflags;
	long esp;
	unsigned short ss, __ssu;
};








# 8 "/usr/include/asm/elf.h" 2 3


typedef unsigned long elf_greg_t;


typedef elf_greg_t elf_gregset_t[(sizeof (struct pt_regs) / sizeof(elf_greg_t)) ];

typedef struct user_i387_struct elf_fpregset_t;

 




 






	 












# 4 "/usr/include/linux/elf.h" 2 3


typedef unsigned long	Elf32_Addr;
typedef unsigned short	Elf32_Half;
typedef unsigned long	Elf32_Off;
typedef long		Elf32_Sword;
typedef unsigned long	Elf32_Word;

 










 








 





















 






 



























 













 


















typedef struct dynamic{
  Elf32_Sword d_tag;
  union{
    Elf32_Sword	d_val;
    Elf32_Addr	d_ptr;
  } d_un;
} Elf32_Dyn;

typedef struct {
  unsigned long long d_tag;		 
  union {
    unsigned long long d_val;
    unsigned long long d_ptr;
  } d_un;
} Elf64_Dyn;

 
















typedef struct elf32_rel {
  Elf32_Addr	r_offset;
  Elf32_Word	r_info;
} Elf32_Rel;

typedef struct elf64_rel {
  unsigned long long r_offset;	 
  unsigned long long r_info;	 
} Elf64_Rel;

typedef struct elf32_rela{
  Elf32_Addr	r_offset;
  Elf32_Word	r_info;
  Elf32_Sword	r_addend;
} Elf32_Rela;

typedef struct elf64_rela {
  unsigned long long r_offset;	 
  unsigned long long r_info;	 
  unsigned long long r_addend;	 
} Elf64_Rela;

typedef struct elf32_sym{
  Elf32_Word	st_name;
  Elf32_Addr	st_value;
  Elf32_Word	st_size;
  unsigned char	st_info;
  unsigned char	st_other;
  Elf32_Half	st_shndx;
} Elf32_Sym;

typedef struct elf64_sym {
  unsigned int	st_name;		 
  unsigned char	st_info;		 
  unsigned char	st_other;		 
  unsigned short st_shndx;		 
  unsigned long long st_value;		 
  unsigned long long st_size;		 
} Elf64_Sym;




typedef struct elf32_hdr{
  unsigned char	e_ident[16 ];
  Elf32_Half	e_type;
  Elf32_Half	e_machine;
  Elf32_Word	e_version;
  Elf32_Addr	e_entry;   
  Elf32_Off	e_phoff;
  Elf32_Off	e_shoff;
  Elf32_Word	e_flags;
  Elf32_Half	e_ehsize;
  Elf32_Half	e_phentsize;
  Elf32_Half	e_phnum;
  Elf32_Half	e_shentsize;
  Elf32_Half	e_shnum;
  Elf32_Half	e_shstrndx;
} Elf32_Ehdr;

typedef struct elf64_hdr {
  unsigned char	e_ident[16];		 
  short int e_type;
  short unsigned int e_machine;
  int   e_version;
  unsigned long long e_entry;		 
  unsigned long long e_phoff;		 
  unsigned long long e_shoff;		 
  int   e_flags;
  short int e_ehsize;
  short int e_phentsize;
  short int e_phnum;
  short int e_shentsize;
  short int e_shnum;
  short int e_shstrndx;
} Elf64_Ehdr;

 





typedef struct elf32_phdr{
  Elf32_Word	p_type;
  Elf32_Off	p_offset;
  Elf32_Addr	p_vaddr;
  Elf32_Addr	p_paddr;
  Elf32_Word	p_filesz;
  Elf32_Word	p_memsz;
  Elf32_Word	p_flags;
  Elf32_Word	p_align;
} Elf32_Phdr;

typedef struct elf64_phdr {
  int p_type;
  int p_flags;
  unsigned long long p_offset;		 
  unsigned long long p_vaddr;		 
  unsigned long long p_paddr;		 
  unsigned long long p_filesz;		 
  unsigned long long p_memsz;		 
  unsigned long long p_align;		 
} Elf64_Phdr;

 


















 





 







 
typedef struct {
  Elf32_Word	sh_name;
  Elf32_Word	sh_type;
  Elf32_Word	sh_flags;
  Elf32_Addr	sh_addr;
  Elf32_Off	sh_offset;
  Elf32_Word	sh_size;
  Elf32_Word	sh_link;
  Elf32_Word	sh_info;
  Elf32_Word	sh_addralign;
  Elf32_Word	sh_entsize;
} Elf32_Shdr;

typedef struct elf64_shdr {
  unsigned int	sh_name;		 
  unsigned int	sh_type;		 
  unsigned long long sh_flags;		 
  unsigned long long sh_addr;		 
  unsigned long long sh_offset;		 
  unsigned long long sh_size;		 
  unsigned int	sh_link;		 
  unsigned int	sh_info;		 
  unsigned long long sh_addralign;	 
  unsigned long long sh_entsize;	 
} Elf64_Shdr;






























 





 
typedef struct elf32_note {
  Elf32_Word	n_namesz;	 
  Elf32_Word	n_descsz;	 
  Elf32_Word	n_type;		 
} Elf32_Nhdr;

 
 




typedef struct elf64_note {
  unsigned int	n_namesz;	 
  unsigned int	n_descsz;	 
  unsigned int	n_type;		 
} Elf64_Nhdr;





extern Elf32_Dyn _DYNAMIC [];















# 103 "boot1.c" 2

# 1 "/usr/include/linux/mman.h" 1 3



# 1 "/usr/include/asm/mman.h" 1 3






















# 39 "/usr/include/asm/mman.h" 3








  

# 4 "/usr/include/linux/mman.h" 2 3





# 104 "boot1.c" 2

# 1 "link.h" 1



# 1 "elf.h" 1





struct nlist
{
  char			*n_name;	 
  long			n_value;	 
  short			n_scnum;	 
  unsigned short	n_type;		 
  char			n_sclass;	 
  char			n_numaux;	 
};


# 4 "link.h" 2


 


struct link_map
{
   

  unsigned long l_addr;	 
  char *l_name;		 
  Elf32_Dyn *l_ld;	 
  struct link_map *l_next;
  struct link_map *l_prev;
};

 


struct r_debug
{
  int r_version;		 
  struct link_map *r_map;	 
  unsigned long r_brk;		 
  enum
  {
    RT_CONSISTENT,
    RT_ADD,
    RT_DELETE
  } r_state;
  unsigned long r_ldbase;	 
};


# 105 "boot1.c" 2


# 1 "i386/sysdep.h" 1

 




 




 





 





 








 







# 58 "i386/sysdep.h"


 












 



 


extern unsigned int _dl_linux_resolver(int dummy, int i);

 








# 107 "boot1.c" 2

# 1 "hash.h" 1






struct dyn_elf{
  unsigned int flags;
  struct elf_resolve * dyn;
  struct dyn_elf * next_handle;   
  struct dyn_elf * next;
};
 
struct elf_resolve{
   

  char * loadaddr;
  char * libname;
  unsigned int dynamic_addr;
  struct elf_resolve * next;
  struct elf_resolve * prev;
   
  enum {elf_lib, elf_executable,program_interpreter, loaded_file} libtype;
  struct dyn_elf * symbol_scope;
  unsigned short usage_count;
  unsigned short int init_flag;
  unsigned int nbucket;
  unsigned int * elf_buckets;
   


  unsigned int nchain;
  unsigned int * chains;
  unsigned int dynamic_info[24];

  unsigned int dynamic_size;
  unsigned int n_phent;
  struct elf32_phdr  * ppnt;
};

# 54 "hash.h"







extern struct dyn_elf     * _dl_symbol_tables;
extern struct elf_resolve * _dl_loaded_modules;
extern struct dyn_elf 	  * _dl_handles;

extern struct elf_resolve * _dl_check_hashed_files(char * libname);
extern struct elf_resolve * _dl_add_elf_hash_table(char * libname, 
					       char * loadaddr, 
					       unsigned int * dynamic_info, 
					       unsigned int dynamic_addr, 
					       unsigned int dynamic_size);
extern char * _dl_find_hash(char * name, struct dyn_elf * rpnt1, 
			    unsigned int instr_addr, 
			    struct elf_resolve * f_tpnt, 
			    int copyrel);

extern int _dl_linux_dynamic_link(void);

# 86 "hash.h"



extern int _dl_write(int, const char *, int);
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 inline int _dl_symbol(char * name)
{
  if(name[0] != '_' || name[1] != 'd' || name[2] != 'l' || name[3] != '_')
    return 0;
  return 1;
}












# 108 "boot1.c" 2

# 1 "linuxelf.h" 1
 






















































 




# 86 "linuxelf.h"









extern _dl_linux_resolve(void);
extern struct elf_resolve * _dl_load_shared_library(struct elf_resolve *,
				char * libname);
extern void * _dl_malloc(int size);
extern int _dl_map_cache(void);
extern int _dl_unmap_cache(void);

extern struct elf_resolve * _dl_load_elf_shared_library(char * libname, int);
int _dl_copy_fixups(struct dyn_elf * tpnt);

extern int linux_run(int argc, char * argv[]);

extern void _dl_parse_lazy_relocation_information(struct elf_resolve * tpnt, int rel_addr,
       int rel_size, int type);

extern int _dl_parse_relocation_information(struct elf_resolve * tpnt, int rel_addr,
       int rel_size, int type);
extern int _dl_parse_copy_information(struct dyn_elf * rpnt, int rel_addr,
       int rel_size, int type);


 













 






 





# 109 "boot1.c" 2

# 1 "i386/syscall.h" 1

extern inline volatile void _dl_exit(int status);
extern inline volatile void _dl_close(int fd);
extern inline int _dl_mmap(void * addr, unsigned int size,
				    unsigned int prot,
				    unsigned int flags, int fd,
				    unsigned int f_offset);





extern inline int _dl_open(char * addr, unsigned int flags);
extern inline int _dl_write(int fd, const char * buf, int len);
extern inline int _dl_read(int fd, const char * buf, int len);
extern inline int _dl_mprotect(const char * addr, int size, int prot);

# 1 "/usr/include/asm/stat.h" 1 3



struct old_stat {
	unsigned short st_dev;
	unsigned short st_ino;
	unsigned short st_mode;
	unsigned short st_nlink;
	unsigned short st_uid;
	unsigned short st_gid;
	unsigned short st_rdev;
	unsigned long  st_size;
	unsigned long  st_atime;
	unsigned long  st_mtime;
	unsigned long  st_ctime;
};

struct stat  {
	unsigned short st_dev;
	unsigned short __pad1;
	unsigned long st_ino;
	unsigned short st_mode;
	unsigned short st_nlink;
	unsigned short st_uid;
	unsigned short st_gid;
	unsigned short st_rdev;
	unsigned short __pad2;
	unsigned long  st_size;
	unsigned long  st_blksize;
	unsigned long  st_blocks;
	unsigned long  st_atime;
	unsigned long  __unused1;
	unsigned long  st_mtime;
	unsigned long  __unused2;
	unsigned long  st_ctime;
	unsigned long  __unused3;
	unsigned long  __unused4;
	unsigned long  __unused5;
};


# 18 "i386/syscall.h" 2


extern inline int _dl_stat(char * filename, struct stat *st);
extern inline int _dl_munmap(char * addr, int size);

 






extern inline volatile void _dl_exit(int status)
{
  int __res;




  __asm__ volatile ("movl %%ecx,%%ebx\n"		    "int $0x80" 		    :  "=a" (__res) : "0" (1 ),"c" ((long)(status)));



}

extern inline volatile void _dl_close(int fd)
{
    int status;

# 56 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%ecx,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (status) 		    : "0" (6 ),"c" ((long)(fd)));





    

}

extern inline int _dl_mmap(void * addr, unsigned int size,
				    unsigned int prot,
				    unsigned int flags, int fd,
				    unsigned int f_offset)
{
  int malloc_buffer;
# 89 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n\t" 		    "pushl %7\n\t" 		    "pushl %6\n\t" 		    "pushl %5\n\t" 		    "pushl %4\n\t" 		    "pushl %3\n\t" 		    "pushl %2\n\t" 		    "movl %%esp,%%ebx\n\t" 		    "int $0x80\n\t" 		    "addl $24,%%esp\n\t" 		    "popl %%ebx\n" 		    : "=a" (malloc_buffer) : "a" (90 ),
# 102 "i386/syscall.h"
		    "rm" (addr), "rm" (size), "rm" (prot), "rm" (flags), 
		    "rm" (fd), "rm" (f_offset));

  return malloc_buffer;
}


extern inline int _dl_open(char * addr, unsigned int flags)
{
  int zfileno;
# 122 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%esi,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (zfileno) 		    : "0" (5 ),"S" ((long)(addr)),"c" ((long)(flags)));







  return zfileno;
}

extern inline int _dl_write(int fd, const char * buf, int len)
{
  int status;
# 148 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%esi,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (status) 		    : "0" (4 ),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len)));






}


extern inline int _dl_read(int fd, const char * buf, int len)
{
  int status;
# 173 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%esi,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (status) 		    : "0" (3 ),"S" ((long)(fd)),"c" ((long)(buf)),"d" ((long)(len)));






}

extern inline int _dl_mprotect(const char * addr, int size, int prot)
{
  int status;
# 197 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%esi,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (status) 		    : "0" (125 ),"S" ((long)(addr)),"c" ((long)(size)),"d" ((long)(prot)));






  return status;
}

extern inline int _dl_stat(char * filename, struct stat *st)
{
  int ret;
# 221 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"                    "movl %%esi,%%ebx\n"                    "int $0x80\n"                     "popl %%ebx\n"                    : "=a" (ret)                     : "0" (106 ),"S" (filename),"c" (st));







  return ret;
}

extern inline int _dl_munmap(char * addr, int size)
{
  int ret;
# 246 "i386/syscall.h"

  __asm__ volatile ("pushl %%ebx\n"		    "movl %%esi,%%ebx\n"		    "int $0x80\n" 		    "popl %%ebx\n"		    : "=a" (ret) 		    : "0" (91 ),"S" ((long)(addr)),"c" ((long)(size)));







  return ret;
}

 




extern inline int _dl_suid_ok(void)
{
  unsigned int uid, euid, gid, egid;
  euid = egid = 0;  





    __asm__ volatile ("int $0x80" : "=a" (uid) : "0" (24 ));
    __asm__ volatile ("int $0x80" : "=a" (euid) : "0" (49 ));
    __asm__ volatile ("int $0x80" : "=a" (gid) : "0" (47 ));
    __asm__ volatile ("int $0x80" : "=a" (egid) : "0" (50 ));


    if(uid == euid && gid == egid)
      return 1;
    else
      return 0;
}

# 110 "boot1.c" 2

# 1 "i386/string.h" 1









extern inline char * _dl_strcpy(char * dest,const char *src);
extern inline char * _dl_strncpy(char * dest,const char *src,size_t count);
extern inline char * _dl_strcat(char * dest,const char * src);
extern inline char * _dl_strncat(char * dest,const char * src,size_t count);
extern inline int _dl_strcmp(const char * cs,const char * ct);
extern inline int _dl_strncmp(const char * cs,const char * ct,size_t count);
extern inline char * _dl_strchr(const char * s,char c);
extern inline char * _dl_strrchr(const char * s,char c);
extern inline size_t _dl_strspn(const char * cs, const char * ct);
extern inline size_t _dl_strcspn(const char * cs, const char * ct);
extern inline char * _dl_strpbrk(const char * cs,const char * ct);
extern inline char * _dl_strstr(const char * cs,const char * ct);
extern inline size_t _dl_strlen(const char * s);
extern inline char * _dl_strtok(char * s,const char * ct);
extern inline void * _dl_memcpy(void * to, const void * from, size_t n);
extern inline void * _dl_memmove(void * dest,const void * src, size_t n);
extern inline int _dl_memcmp(const void * cs,const void * ct,size_t count);
extern inline void * _dl_memchr(const void * cs,char c,size_t count);
extern inline void * _dl_memset(void * s,char c,size_t count);

 










 
extern inline char * _dl_strcpy(char * dest,const char *src)
{
__asm__("cld\n"
	"1:\tlodsb\n\t"
	"stosb\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b"
	:  
	:"S" (src),"D" (dest):"si","di","ax","memory");
return dest;
}

extern inline char * _dl_strncpy(char * dest,const char *src,size_t count)
{
__asm__("cld\n"
	"1:\tdecl %2\n\t"
	"js 2f\n\t"
	"lodsb\n\t"
	"stosb\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b\n\t"
	"rep\n\t"
	"stosb\n"
	"2:"
	:  
	:"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
return dest;
}

extern inline char * _dl_strcat(char * dest,const char * src)
{
__asm__("cld\n\t"
	"repne\n\t"
	"scasb\n\t"
	"decl %1\n"
	"1:\tlodsb\n\t"
	"stosb\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b"
	:  
	:"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
return dest;
}

extern inline char * _dl_strncat(char * dest,const char * src,size_t count)
{
__asm__("cld\n\t"
	"repne\n\t"
	"scasb\n\t"
	"decl %1\n\t"
	"movl %4,%3\n"
	"1:\tdecl %3\n\t"
	"js 2f\n\t"
	"lodsb\n\t"
	"stosb\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b\n"
	"2:\txorl %2,%2\n\t"
	"stosb"
	:  
	:"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
	:"si","di","ax","cx","memory");
return dest;
}

extern inline int _dl_strcmp(const char * cs,const char * ct)
{
register int __res;
__asm__("cld\n"
	"5:\tlodsb\n\t"
	"scasb\n\t"
	"jne 6f\n\t"
	"testb %%al,%%al\n\t"
	"jne 5b\n\t"
	"xorl %%eax,%%eax\n\t"
	"jmp 7f\n"
	"6:\tmovl $1,%%eax\n\t"
	"jb 7f\n\t"
	"negl %%eax\n"
	"7:"
	:"=a" (__res):"D" (cs),"S" (ct):"si","di");
return __res;
}

extern inline int _dl_strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
__asm__("cld\n"
	"1:\tdecl %3\n\t"
	"js 2f\n\t"
	"lodsb\n\t"
	"scasb\n\t"
	"jne 3f\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b\n"
	"2:\txorl %%eax,%%eax\n\t"
	"jmp 4f\n"
	"3:\tmovl $1,%%eax\n\t"
	"jb 4f\n\t"
	"negl %%eax\n"
	"4:"
	:"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");
return __res;
}

extern inline char * _dl_strchr(const char * s,char c)
{
register char * __res;
__asm__("cld\n\t"
	"movb %%al,%%ah\n"
	"1:\tlodsb\n\t"
	"cmpb %%ah,%%al\n\t"
	"je 2f\n\t"
	"testb %%al,%%al\n\t"
	"jne 1b\n\t"
	"movl $1,%1\n"
	"2:\tmovl %1,%0\n\t"
	"decl %0"
	:"=a" (__res):"S" (s),"0" (c):"si");
return __res;
}

extern inline char * _dl_strrchr(const char * s,char c)
{
register char * __res;
__asm__("cld\n\t"
	"movb %%al,%%ah\n"
	"1:\tlodsb\n\t"
	"cmpb %%ah,%%al\n\t"
	"jne 2f\n\t"
	"movl %%esi,%0\n\t"
	"decl %0\n"
	"2:\ttestb %%al,%%al\n\t"
	"jne 1b"
	:"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
return __res;
}

extern inline size_t _dl_strspn(const char * cs, const char * ct)
{
register char * __res;
__asm__("cld\n\t"
	"movl %4,%%edi\n\t"
	"repne\n\t"
	"scasb\n\t"
	"notl %%ecx\n\t"
	"decl %%ecx\n\t"
	"movl %%ecx,%%edx\n"
	"1:\tlodsb\n\t"
	"testb %%al,%%al\n\t"
	"je 2f\n\t"
	"movl %4,%%edi\n\t"
	"movl %%edx,%%ecx\n\t"
	"repne\n\t"
	"scasb\n\t"
	"je 1b\n"
	"2:\tdecl %0"
	:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
	:"ax","cx","dx","di");
return __res-cs;
}

extern inline size_t _dl_strcspn(const char * cs, const char * ct)
{
register char * __res;
__asm__("cld\n\t"
	"movl %4,%%edi\n\t"
	"repne\n\t"
	"scasb\n\t"
	"notl %%ecx\n\t"
	"decl %%ecx\n\t"
	"movl %%ecx,%%edx\n"
	"1:\tlodsb\n\t"
	"testb %%al,%%al\n\t"
	"je 2f\n\t"
	"movl %4,%%edi\n\t"
	"movl %%edx,%%ecx\n\t"
	"repne\n\t"
	"scasb\n\t"
	"jne 1b\n"
	"2:\tdecl %0"
	:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
	:"ax","cx","dx","di");
return __res-cs;
}

extern inline char * _dl_strpbrk(const char * cs,const char * ct)
{
register char * __res;
__asm__("cld\n\t"
	"movl %4,%%edi\n\t"
	"repne\n\t"
	"scasb\n\t"
	"notl %%ecx\n\t"
	"decl %%ecx\n\t"
	"movl %%ecx,%%edx\n"
	"1:\tlodsb\n\t"
	"testb %%al,%%al\n\t"
	"je 2f\n\t"
	"movl %4,%%edi\n\t"
	"movl %%edx,%%ecx\n\t"
	"repne\n\t"
	"scasb\n\t"
	"jne 1b\n\t"
	"decl %0\n\t"
	"jmp 3f\n"
	"2:\txorl %0,%0\n"
	"3:"
	:"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
	:"ax","cx","dx","di");
return __res;
}

extern inline char * _dl_strstr(const char * cs,const char * ct)
{
register char * __res;
__asm__("cld\n\t" 	"movl %4,%%edi\n\t"

	"repne\n\t"
	"scasb\n\t"
	"notl %%ecx\n\t"
	"decl %%ecx\n\t"	 
	"movl %%ecx,%%edx\n"
	"1:\tmovl %4,%%edi\n\t"
	"movl %%esi,%%eax\n\t"
	"movl %%edx,%%ecx\n\t"
	"repe\n\t"
	"cmpsb\n\t"
	"je 2f\n\t"		 
	"xchgl %%eax,%%esi\n\t"
	"incl %%esi\n\t"
	"cmpb $0,-1(%%eax)\n\t"
	"jne 1b\n\t"
	"xorl %%eax,%%eax\n\t"
	"2:"
	:"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
	:"cx","dx","di","si");
return __res;
}

extern inline size_t _dl_strlen(const char * s)
{
register int __res;
__asm__("cld\n\t"
	"repne\n\t"
	"scasb\n\t"
	"notl %0\n\t"
	"decl %0"
	:"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
return __res;
}

extern char * ___strtok;

extern inline char * _dl_strtok(char * s,const char * ct)
{
register char * __res;
__asm__("testl %1,%1\n\t"
	"jne 1f\n\t"
	"testl %0,%0\n\t"
	"je 8f\n\t"
	"movl %0,%1\n"
	"1:\txorl %0,%0\n\t"
	"movl $-1,%%ecx\n\t"
	"xorl %%eax,%%eax\n\t"
	"cld\n\t"
	"movl %4,%%edi\n\t"
	"repne\n\t"
	"scasb\n\t"
	"notl %%ecx\n\t"
	"decl %%ecx\n\t"
	"je 7f\n\t"			 
	"movl %%ecx,%%edx\n"
	"2:\tlodsb\n\t"
	"testb %%al,%%al\n\t"
	"je 7f\n\t"
	"movl %4,%%edi\n\t"
	"movl %%edx,%%ecx\n\t"
	"repne\n\t"
	"scasb\n\t"
	"je 2b\n\t"
	"decl %1\n\t"
	"cmpb $0,(%1)\n\t"
	"je 7f\n\t"
	"movl %1,%0\n"
	"3:\tlodsb\n\t"
	"testb %%al,%%al\n\t"
	"je 5f\n\t"
	"movl %4,%%edi\n\t"
	"movl %%edx,%%ecx\n\t"
	"repne\n\t"
	"scasb\n\t"
	"jne 3b\n\t"
	"decl %1\n\t"
	"cmpb $0,(%1)\n\t"
	"je 5f\n\t"
	"movb $0,(%1)\n\t"
	"incl %1\n\t"
	"jmp 6f\n"
	"5:\txorl %1,%1\n"
	"6:\tcmpb $0,(%0)\n\t"
	"jne 7f\n\t"
	"xorl %0,%0\n"
	"7:\ttestl %0,%0\n\t"
	"jne 8f\n\t"
	"movl %0,%1\n"
	"8:"
	:"=b" (__res),"=S" (___strtok)
	:"0" (___strtok),"1" (s),"g" (ct)
	:"ax","cx","dx","di","memory");
return __res;
}

extern inline void * _dl_memcpy(void * to, const void * from, size_t n)
{
__asm__("cld\n\t"
	"movl %%edx, %%ecx\n\t"
	"shrl $2,%%ecx\n\t"
	"rep ; movsl\n\t"
	"testb $1,%%dl\n\t"
	"je 1f\n\t"
	"movsb\n"
	"1:\ttestb $2,%%dl\n\t"
	"je 2f\n\t"
	"movsw\n"
	"2:\n"
	:  
	:"d" (n),"D" ((long) to),"S" ((long) from)
	: "cx","di","si","memory");
return (to);
}

extern inline void * _dl_memmove(void * dest,const void * src, size_t n)
{
if (dest<src)
__asm__("cld\n\t"
	"rep\n\t"
	"movsb"
	:  
	:"c" (n),"S" (src),"D" (dest)
	:"cx","si","di");
else
__asm__("std\n\t"
	"rep\n\t"
	"movsb\n\t"
	"cld"
	:  
	:"c" (n),
	 "S" (n-1+(const char *)src),
	 "D" (n-1+(char *)dest)
	:"cx","si","di","memory");
return dest;
}

extern inline int _dl_memcmp(const void * cs,const void * ct,size_t count)
{
register int __res;
__asm__("cld\n\t"
	"repe\n\t"
	"cmpsb\n\t"
	"je 1f\n\t"
	"movl $1,%%eax\n\t"
	"jb 1f\n\t"
	"negl %%eax\n"
	"1:"
	:"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
	:"si","di","cx");
return __res;
}

extern inline void * _dl_memchr(const void * cs,char c,size_t count)
{
register void * __res;
if (!count)
	return ((void *) 0) ;
__asm__("cld\n\t"
	"repne\n\t"
	"scasb\n\t"
	"je 1f\n\t"
	"movl $1,%0\n"
	"1:\tdecl %0"
	:"=D" (__res):"a" (c),"D" (cs),"c" (count)
	:"cx");
return __res;
}

extern inline void * _dl_memset(void * s,char c,size_t count)
{
__asm__("cld\n\t"
	"rep\n\t"
	"stosb"
	:  
	:"a" (c),"D" (s),"c" (count)
	:"cx","di","memory");
return s;
}


# 111 "boot1.c" 2


# 1 "../config.h" 1


















typedef void (*loadptr)(int func, ...);
typedef void (*callbackptr)(int ver, int nlibs, char **libs, 
		int nmods, char **mods);


















typedef struct {
	char magic   [(sizeof "ld.so-"  -1) ];
	char version [(sizeof "1.7.0"  -1) ];
	int nlibs;
} header_t;

typedef struct {
	int flags;
	int sooffset;
	int liboffset;
} libentry_t;
# 113 "boot1.c" 2




static char * _dl_malloc_addr, *_dl_mmap_zero;
char * _dl_library_path = 0;  
char *_dl_preload = 0;  
char *_dl_progname = "/lib/ld-linux.so.1";
static char * _dl_not_lazy = 0;
static char * _dl_warn = 0;  
static char * _dl_trace_loaded_objects = 0;
static int (*_dl_elf_main)(int, char **, char**);

static int (*_dl_elf_init)(void);

void * (*_dl_malloc_function)(int size) = ((void *) 0) ;

struct r_debug * _dl_debug_addr = ((void *) 0) ;

unsigned int * _dl_brkp; 

unsigned int * _dl_envp;


 









# 157 "boot1.c"
extern _dl_linux_resolve(void);
extern int _dl_interpreter_exit(int);
extern char * _dl_strdup(const char *);
extern char * _dl_getenv(char * symbol, char ** envp);
extern void _dl_unsetenv(char * symbol, char ** envp);
extern int _dl_fixup(struct elf_resolve * tpnt);

 





typedef struct elf32_rel ELF_RELOC;


 




void _dl_debug_state()
{
  return;
}

void _dl_boot(int args);

void _dl_boot(int args){
  unsigned int argc;
  char ** argv, ** envp;
  int status;

  unsigned int load_addr;
  unsigned int * got;
  unsigned int * aux_dat;
  int goof = 0;
  struct elf32_hdr  * header;
  struct elf_resolve * tpnt;
  struct dyn_elf * rpnt;
  struct elf_resolve * app_tpnt;
  unsigned int brk_addr;
  unsigned int dl_data[14 +1];
  unsigned char * malloc_buffer, *mmap_zero;
  int (*_dl_atexit)(void *);
  int * lpnt;
  struct dynamic * dpnt;
  unsigned int *hash_addr;
  struct r_debug * debug_addr;
  unsigned int *chains;
  int indx;
  int _dl_secure;

   


   aux_dat  = ((unsigned int*) &   args ) ;
  argc = *(aux_dat - 1);
  argv = (char **) aux_dat;
  aux_dat += argc;   
  aux_dat++;   
  envp = (char **) aux_dat;
  while(*aux_dat) aux_dat++;   
  aux_dat++;   
  dl_data[11 ] = -1;  
  while(*aux_dat)
    {
      unsigned int * ad1;
      ad1 = aux_dat + 1;
      if( *aux_dat <= 14  ) dl_data[*aux_dat] = *ad1;
      aux_dat += 2;
    }

   

  load_addr = dl_data[7 ];

  __asm__("\tmovl %%ebx,%0\n\t" : "=a" ( got )) ;
  dpnt = (struct dynamic *) (*got + load_addr);
 
   



  {
     
    int zfileno;

 









     
    mmap_zero = malloc_buffer = (unsigned char *) _dl_mmap((void*) 0, 4096,
			     0x1  | 0x2 , 
			     0x02  | 0x20 , ((-1 & (~zfileno)) | zfileno) , 0);
    if((((int) mmap_zero ) < 0 && ((int) mmap_zero ) >= - 4096 ) ) {
	_dl_write(2,  "dl_boot: mmap of /dev/zero failed!\n" , _dl_strlen( "dl_boot: mmap of /dev/zero failed!\n" )); ;
	_dl_exit(13);
    }
  }

  tpnt = ((void *) (malloc_buffer +=  sizeof(struct elf_resolve) , malloc_buffer -  sizeof(struct elf_resolve) )) ;
  malloc_buffer = (char *) (((unsigned int) malloc_buffer + 3) & ~(3)) ;
  _dl_memset (tpnt, 0, sizeof (*tpnt));
  app_tpnt = ((void *) (malloc_buffer +=  sizeof(struct elf_resolve) , malloc_buffer -  sizeof(struct elf_resolve) )) ;
  malloc_buffer = (char *) (((unsigned int) malloc_buffer + 3) & ~(3)) ;
  _dl_memset (app_tpnt, 0, sizeof (*app_tpnt));

   


  debug_addr = ((void *) (malloc_buffer +=  sizeof(struct r_debug) , malloc_buffer -  sizeof(struct r_debug) )) ;
  malloc_buffer = (char *) (((unsigned int) malloc_buffer + 3) & ~(3)) ;
  _dl_memset (debug_addr, 0, sizeof (*debug_addr));

   


  while(dpnt->d_tag)
    {
      tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
      if(dpnt->d_tag == 22  ||
	 1 ) tpnt->dynamic_info[22 ] = 1;
      dpnt++;
    }

  {
    struct elf32_phdr  * ppnt;
    int i;
    
    ppnt = (struct elf32_phdr  *) dl_data[3 ];
    for(i=0; i<dl_data[5 ]; i++, ppnt++)
      if(ppnt->p_type == 2 ) {
	dpnt = (struct dynamic *) ppnt->p_vaddr;
	while(dpnt->d_tag)
	  {
	    if(dpnt->d_tag > 23 ) {dpnt++; continue; }
	    app_tpnt->dynamic_info[dpnt->d_tag] = dpnt->d_un.d_val;
	    if(dpnt->d_tag == 21 ) dpnt->d_un.d_val = (int) debug_addr;
	    if(dpnt->d_tag == 22  ||
	       1 ) app_tpnt->dynamic_info[22 ] = 1;
	    dpnt++;
	  }
      }
  }

   


  hash_addr = (unsigned int *) (tpnt->dynamic_info[4 ]+load_addr);
  tpnt->nbucket = *hash_addr++;
  tpnt->nchain = *hash_addr++;
  tpnt->elf_buckets = hash_addr;
  hash_addr += tpnt->nbucket;
  chains = hash_addr;

   



  {
    struct elf32_phdr  * ppnt;
    int i;

     
    if(tpnt->dynamic_info[22 ]) {
      header = (struct elf32_hdr  *) dl_data[7 ];	    
      ppnt = (struct elf32_phdr  *) (dl_data[7 ] + header->e_phoff);
      for(i=0; i<header->e_phnum ; i++, ppnt++) {
	if(ppnt->p_type == 1  && !(ppnt->p_flags & 0x2 ))
		_dl_mprotect((void *) (load_addr + (ppnt->p_vaddr & 0xfffff000)),
			      (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
			      0x1  | 0x2  | 0x4 );
      }
    }
    
     
    if(app_tpnt->dynamic_info[22 ]) {
      ppnt = (struct elf32_phdr  *) dl_data[3 ];
      for(i=0; i<dl_data[5 ]; i++, ppnt++) {
	if(ppnt->p_type == 1  && !(ppnt->p_flags & 0x2 ))
	  _dl_mprotect((void *) (ppnt->p_vaddr & 0xfffff000),
		       (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
		       0x1  | 0x2  | 0x4 );
      }
    }
  }

   


  goof = 0;
  for(indx=0; indx < 2; indx++)
    {
      int i;
      ELF_RELOC * rpnt;
      unsigned int * reloc_addr;
      unsigned int symbol_addr;
      int symtab_index;
      unsigned int rel_addr, rel_size;

  




      rel_addr = (indx ? tpnt->dynamic_info[23 ] : tpnt->dynamic_info[17 ]);
      rel_size = (indx ? tpnt->dynamic_info[2 ] : tpnt->dynamic_info[18 ]);



      if(!rel_addr) continue;

       
      rpnt = (ELF_RELOC *) (rel_addr + load_addr);
      for(i=0; i< rel_size; i+=sizeof(ELF_RELOC), rpnt++){
	reloc_addr = (int *) (load_addr + (int)rpnt->r_offset);
	symtab_index = (( rpnt->r_info ) >> 8) ;
	symbol_addr = 0;
	if(symtab_index) {
	  char * strtab;
	  struct elf32_sym * symtab;

	  symtab = (struct elf32_sym *) (tpnt->dynamic_info[6 ]+load_addr);
	  strtab = (char *) (tpnt->dynamic_info[5 ]+load_addr);

	   



	  if (!_dl_symbol(strtab + symtab[symtab_index].st_name)) continue;

	  symbol_addr = load_addr + symtab[symtab_index].st_value;

	  if(!symbol_addr) {
	     



	    _dl_write(2,  "ELF dynamic loader - unable to self-bootstrap - symbol " , _dl_strlen( "ELF dynamic loader - unable to self-bootstrap - symbol " )); ;
	    _dl_write(2,  strtab + symtab[symtab_index].st_name , _dl_strlen( strtab + symtab[symtab_index].st_name )); ;
	    _dl_write(2,  " undefined.\n" , _dl_strlen( " undefined.\n" )); ;
	    goof++;
	  }
	}
	 


	switch((( ( rpnt )->r_info ) & 0xff) ){	case 1 :	*  reloc_addr  +=   symbol_addr ;	break;	case 2 :	*  reloc_addr  +=   symbol_addr  - (unsigned int)   reloc_addr ;	break;	case 6 :	case 7 :	*  reloc_addr  =   symbol_addr ;	break;	case 8 :	*  reloc_addr  += (unsigned int)   load_addr ;	break;	default:	_dl_exit(1);	} ;
      }
    }

  if (goof)    _dl_exit(14);

   





  _dl_malloc_addr = malloc_buffer;

  _dl_mmap_zero = mmap_zero;
 

 




  lpnt = (int *) (tpnt->dynamic_info[3 ] + load_addr);
  {	 lpnt [2] = (int) _dl_linux_resolve;  lpnt [1] = (int)   tpnt ; } ;

   


  tpnt->next = 0;
  tpnt->libname = 0;
  tpnt->libtype = program_interpreter;

  { struct elf32_hdr  * epnt;
    struct elf32_phdr  * ppnt;
    int i;

    epnt = (struct elf32_hdr  *) dl_data[7 ];
    tpnt->n_phent = epnt->e_phnum;
    tpnt->ppnt = ppnt = (struct elf32_phdr  *) (load_addr + epnt->e_phoff);
    for(i=0;i < epnt->e_phnum; i++, ppnt++){
      if(ppnt->p_type == 2 ) {
	tpnt->dynamic_addr = ppnt->p_vaddr + load_addr;
	tpnt->dynamic_size = ppnt->p_filesz;
      }
    }
  }

  tpnt->chains = chains;
  tpnt->loadaddr = (char *) load_addr;

  brk_addr = 0;
  rpnt = ((void *) 0) ;

   



  {
    struct elf32_phdr  * ppnt;
    int i;

    ppnt = (struct elf32_phdr  *) dl_data[3 ];
    for(i=0; i<dl_data[5 ]; i++, ppnt++) {
      if(ppnt->p_type == 1 ) {
	if(ppnt->p_vaddr + ppnt->p_memsz > brk_addr) 
	  brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
      }
      if(ppnt->p_type == 2 ) {




	 
	app_tpnt = _dl_add_elf_hash_table("", 0, 
			    app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
	_dl_loaded_modules->libtype = elf_executable;
	_dl_loaded_modules->ppnt = (struct elf32_phdr  *) dl_data[3 ];
	_dl_loaded_modules->n_phent = dl_data[5 ];
	_dl_symbol_tables = rpnt = 
	   (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
	_dl_memset (rpnt, 0, sizeof (*rpnt));
	rpnt->dyn = _dl_loaded_modules;
	app_tpnt->usage_count++;
	app_tpnt->symbol_scope = _dl_symbol_tables;
	lpnt = (int *) (app_tpnt->dynamic_info[3 ]);

	if (lpnt)

	  {	 lpnt [2] = (int) _dl_linux_resolve;  lpnt [1] = (int)   _dl_loaded_modules ; } ;
      }
      if(ppnt->p_type == 3 ) {  

	tpnt->libname =  _dl_strdup((char *) ppnt->p_offset +(dl_data[3 ] & 0xfffff000));
      }
    }
  }

  if (argv[0])
    _dl_progname = argv[0];

   

  {
    _dl_not_lazy = _dl_getenv("LD_BIND_NOW",envp);

    if ( (dl_data[11 ] == -1 && _dl_suid_ok()) ||
	 (dl_data[11 ] != -1 && dl_data[11 ] == dl_data[12 ] &&
	  dl_data[13 ] == dl_data[14 ]))
    {
      _dl_secure = 0;
      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
      _dl_library_path = _dl_getenv("LD_LIBRARY_PATH",envp);
    }
    else
    {
      _dl_secure = 1;
      _dl_preload = _dl_getenv("LD_PRELOAD", envp);
      _dl_unsetenv("LD_AOUT_PRELOAD", envp);
      _dl_unsetenv("LD_LIBRARY_PATH", envp);
      _dl_unsetenv("LD_AOUT_LIBRARY_PATH", envp);
      _dl_library_path = ((void *) 0) ;
    }
  }

  _dl_trace_loaded_objects = _dl_getenv("LD_TRACE_LOADED_OBJECTS", envp);

   





  _dl_map_cache();


  {
    struct elf_resolve *tcurr;
    struct elf_resolve *tpnt1;
    char *lpnt;

    if (_dl_preload) {
      char c, *str, *str2;

      str = _dl_preload;
      while (*str == ':' || *str == ' ' || *str == '\t')
	str++;
      while (*str) {
	str2 = str;
	while (*str2 && *str2 != ':' && *str2 != ' ' && *str2 != '\t')
	  str2++;
	c = *str2;
	*str2 = '\0';
	if (!_dl_secure || _dl_strchr(str, '/') == ((void *) 0) ) {
	  tpnt1 = _dl_load_shared_library(((void *) 0) , str);
	  if (!tpnt1) {
	    if (_dl_trace_loaded_objects)
	      _dl_fdprintf(1, "\t%s => not found\n", str);
	    else {
	      _dl_fdprintf(2, "%s: can't load library '%s'\n",
			   _dl_progname, str);
	      _dl_exit(15);
	    }
	  } else {
	    if (_dl_trace_loaded_objects && !tpnt1->usage_count) {
	       

	      if (_dl_strcmp(_dl_progname, str) != 0)
		_dl_fdprintf(1, "\t%s => %s (0x%x)\n", str, tpnt1->libname,
			     (unsigned)tpnt1->loadaddr);
	    }
	    rpnt->next = 
	      (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
	    _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
	    rpnt = rpnt->next;
	    tpnt1->usage_count++;
	    tpnt1->symbol_scope = _dl_symbol_tables;
	    tpnt1->libtype = elf_lib;
	    rpnt->dyn = tpnt1;
	  }
	}
	*str2 = c;
	str = str2;
	while (*str == ':' || *str == ' ' || *str == '\t')
	  str++;
      }
    }


    {
      int fd;
      struct stat st;
      char *preload;

      if (!_dl_stat("/etc/ld.so.preload" , &st)) {
	if ((fd = _dl_open("/etc/ld.so.preload" , 00 )) < 0) {
	  _dl_fdprintf(2, "%s: can't open file '%s'\n", _dl_progname, 
		       "/etc/ld.so.preload" );
	} else {
	  preload = (caddr_t)_dl_mmap(0, st.st_size+1, 0x1 | 0x2 , 
				      0x02 , fd, 0);
	  _dl_close (fd);
	  if (preload == (caddr_t)-1) {
	    _dl_fdprintf(2, "%s: can't map file '%s'\n", _dl_progname, 
			 "/etc/ld.so.preload" );
	  } else {
	    char c, *cp, *cp2;

	     
	    for (cp = preload; *cp;  ) {
	      if (*cp == ':' || *cp == '\t' || *cp == '\n') {
		*cp++ = ' ';
	      } else if (*cp == '#') {
		do
		  *cp++ = ' ';
		while (*cp != '\n' && *cp != '\0');
	      } else {
		cp++;
	      }
	    }

	     
	    for (cp = preload; *cp && *cp == ' '; cp++)
	       ;

	    while (*cp) {
	       
	      for (cp2 = cp; *cp && *cp != ' '; cp++)
		 ;
	      c = *cp;
	      *cp = '\0';

	      tpnt1 = _dl_load_shared_library(((void *) 0) , cp2);
	      if (!tpnt1) {
		if (_dl_trace_loaded_objects)
		  _dl_fdprintf(1, "\t%s => not found\n", cp2);
		else {
		  _dl_fdprintf(2, "%s: can't load library '%s'\n",
			       _dl_progname, cp2);
		  _dl_exit(15);
		}
	      } else {
		if (_dl_trace_loaded_objects && !tpnt1->usage_count)
		  _dl_fdprintf(1, "\t%s => %s (0x%x)\n", cp2, tpnt1->libname,
			       (unsigned)tpnt1->loadaddr);
                rpnt->next = 
		  (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
		_dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
		rpnt = rpnt->next;
		tpnt1->usage_count++;
		tpnt1->symbol_scope = _dl_symbol_tables;
		tpnt1->libtype = elf_lib;
		rpnt->dyn = tpnt1;
	      }

	       
	      *cp = c;
	      for ( ; *cp && *cp == ' '; cp++)
		 ;
	    }

	    _dl_munmap(preload, st.st_size+1);
	  }
	}
      }
    }


    for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next)
    {
      for (dpnt = (struct dynamic *)tcurr->dynamic_addr; dpnt->d_tag; dpnt++)
      {
	if(dpnt->d_tag == 1 )
	{
	  lpnt = tcurr->loadaddr + tcurr->dynamic_info[5 ] + 
	    dpnt->d_un.d_val;
	  if (tpnt && _dl_strcmp(lpnt, tpnt->libname) == 0)
	  {
	    struct elf_resolve * ttmp;
	    ttmp = _dl_loaded_modules;
	    while (ttmp->next) 
	      ttmp = ttmp->next;
	    ttmp->next = tpnt;
	    tpnt->prev = ttmp;
	    tpnt->next = ((void *) 0) ;
	    rpnt->next = 
	      (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
	    _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
	    rpnt = rpnt->next;
	    rpnt->dyn = tpnt;
	    tpnt->usage_count++;
	    tpnt->symbol_scope = _dl_symbol_tables;
	    tpnt = ((void *) 0) ;
	    continue;
	  }
	  if (!(tpnt1 = _dl_load_shared_library(tcurr, lpnt)))
	  {
	    if (_dl_trace_loaded_objects)
	      _dl_fdprintf(1, "\t%s => not found\n", lpnt);
	    else
	    {
	      _dl_fdprintf(2, "%s: can't load library '%s'\n",
			   _dl_progname, lpnt);
	      _dl_exit(16);
	    }
	  }
	  else
	  {
	    if (_dl_trace_loaded_objects && !tpnt1->usage_count)
	      _dl_fdprintf(1, "\t%s => %s (0x%x)\n", lpnt, tpnt1->libname,
			   (unsigned)tpnt1->loadaddr);
	    rpnt->next = 
	      (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
	    _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
	    rpnt = rpnt->next;
	    tpnt1->usage_count++;
	    tpnt1->symbol_scope = _dl_symbol_tables;
	    tpnt1->libtype = elf_lib;
	    rpnt->dyn = tpnt1;
	  }
	}
      }
    }
  }


  _dl_unmap_cache();


      
  if(_dl_trace_loaded_objects)
    {
      _dl_warn = _dl_getenv("LD_WARN", envp);
      if (!_dl_warn) _dl_exit(0);
    }

   




  if(tpnt) {
    struct elf_resolve * tcurr;

    tcurr = _dl_loaded_modules;
    if (tcurr)
      while(tcurr->next) tcurr = tcurr->next;
    tpnt->next = ((void *) 0) ;
    tpnt->usage_count++;

    if (tcurr) {
      tcurr->next = tpnt;
      tpnt->prev = tcurr;
    }
    else {
      _dl_loaded_modules = tpnt;
      tpnt->prev = ((void *) 0) ;
    }
    if (rpnt) {
      rpnt->next = 
	(struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
      _dl_memset (rpnt->next, 0, sizeof (*(rpnt->next)));
      rpnt = rpnt->next;
    } else {
      rpnt = 	(struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
      _dl_memset (rpnt, 0, sizeof (*(rpnt->next)));
    }
    rpnt->dyn = tpnt;
    tpnt = ((void *) 0) ;
  }

   






  goof = _dl_loaded_modules ? _dl_fixup(_dl_loaded_modules) : 0;


   




  if (_dl_symbol_tables)
    goof += _dl_copy_fixups(_dl_symbol_tables);

  if(goof || _dl_trace_loaded_objects) _dl_exit(0);

   







  _dl_brkp = (unsigned int *) _dl_find_hash("___brk_addr", ((void *) 0) , 1, ((void *) 0) , 0);
  if (_dl_brkp) *_dl_brkp = brk_addr;




  _dl_envp = (unsigned int *) _dl_find_hash("__environ", ((void *) 0) , 1, ((void *) 0) , 0);


  if (_dl_envp) *_dl_envp = (unsigned int) envp;

  {
    int i;
    struct elf32_phdr  * ppnt;

   

  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
    for(ppnt = tpnt->ppnt, i=0; i < tpnt->n_phent; i++, ppnt++)
      if(ppnt->p_type == 1  && !(ppnt->p_flags & 0x2 ) &&
	 tpnt->dynamic_info[22 ])
	_dl_mprotect((void *) (tpnt->loadaddr + (ppnt->p_vaddr & 0xfffff000)),
		     (ppnt->p_vaddr & 0xfff) + (unsigned int) ppnt->p_filesz,
		     ( ((( ppnt->p_flags ) & 0x4 ) ? 0x1  : 0) | ((( ppnt->p_flags ) & 0x2 ) ? 0x2  : 0) | ((( ppnt->p_flags ) & 0x1 ) ? 0x4  : 0)) );

  }

  _dl_atexit = (int (*)(void *)) _dl_find_hash("atexit", ((void *) 0) , 1, ((void *) 0) , 0);

   




  debug_addr->r_map = (struct link_map *) _dl_loaded_modules;
  debug_addr->r_version = 1;
  debug_addr->r_ldbase = load_addr;
  debug_addr->r_brk = (unsigned long) &_dl_debug_state;
  _dl_debug_addr = debug_addr;
  debug_addr->r_state = RT_CONSISTENT;
   

  ((void (*)(void))debug_addr->r_brk)();

  for(tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next)
    {
       


      if (tpnt->libtype == program_interpreter ||
	tpnt->libtype == elf_executable) continue;
      if (tpnt->init_flag & 8 ) continue;
      tpnt->init_flag |= 8 ;
      
      if(tpnt->dynamic_info[12 ]) {
	_dl_elf_init = (int (*)(void)) (tpnt->loadaddr + 
				    tpnt->dynamic_info[12 ]);
	(*_dl_elf_init)();
      }
      if(_dl_atexit && tpnt->dynamic_info[13 ])
      {
        (*_dl_atexit)(tpnt->loadaddr + tpnt->dynamic_info[13 ]);
      }

# 885 "boot1.c"


   }

   
  _dl_elf_main = (int (*)(int, char**, char**)) dl_data[9 ];


   


  __asm__ volatile ("leave\n\t" "jmp *%%eax\n\t"	: "=a" (status) :	"d" (_dl_interpreter_exit), "a" (_dl_elf_main)) ;
}

int _dl_fixup(struct elf_resolve * tpnt)
{
  int goof = 0;
  if(tpnt->next) goof += _dl_fixup(tpnt->next);

  if(tpnt->dynamic_info[17 ]) {




    if (tpnt->init_flag & 2 ) return goof;
    tpnt->init_flag |= 2 ;
   
    goof += _dl_parse_relocation_information(tpnt, tpnt->dynamic_info[17 ],
					     tpnt->dynamic_info[18 ], 0);

  }
  if(tpnt->dynamic_info[7 ]) {







    _dl_fdprintf(2, "%s: can't handle RELA relocation records\n", _dl_progname);
    _dl_exit(18);

  }
  if(tpnt->dynamic_info[23 ])
    {
      if (tpnt->init_flag & 4 ) return goof;
      tpnt->init_flag |= 4 ;
      
      if(! _dl_not_lazy || *_dl_not_lazy == 0)
	_dl_parse_lazy_relocation_information(tpnt, tpnt->dynamic_info[23 ],
					      tpnt->dynamic_info[2 ], 0);
      else
	goof +=  _dl_parse_relocation_information(tpnt,
						  tpnt->dynamic_info[23 ],
						  tpnt->dynamic_info[2 ], 0);
    }
  return goof;
}

void * _dl_malloc(int size) {
  void * retval;

  if(_dl_malloc_function)
  	return (*_dl_malloc_function)(size);

  if(_dl_malloc_addr-_dl_mmap_zero+size>4096) {
	_dl_mmap_zero = _dl_malloc_addr = (unsigned char *) _dl_mmap((void*) 0, size,
  				0x1  | 0x2 , 
  				0x02  | 0x20 , -1, 0);
  	if((((int) _dl_mmap_zero ) < 0 && ((int) _dl_mmap_zero ) >= - 4096 ) ) {
  	    _dl_fdprintf(2, "%s: can't map '/dev/zero'\n", _dl_progname);
  	    _dl_exit(20);
  	}
  }
  retval = _dl_malloc_addr;
  _dl_malloc_addr += size;

   



  _dl_malloc_addr = (char *) (((unsigned int) _dl_malloc_addr + 3) & ~(3));
  return retval;
}

char * _dl_getenv(char *symbol, char **envp)
{
  char *pnt;
  char *pnt1;
  while ((pnt = *envp++)) {
    pnt1 = symbol;
    while (*pnt && *pnt == *pnt1)
      pnt1++, pnt++;
    if (!*pnt || *pnt != '=' || *pnt1)
      continue;
    return pnt+1;
  }
  return 0;
}

void _dl_unsetenv(char *symbol, char **envp)
{
  char *pnt;
  char *pnt1;
  char **newenvp = envp;
  for (pnt = *envp; pnt; pnt = *++envp) {
    pnt1 = symbol;
    while (*pnt && *pnt == *pnt1)
      pnt1++, pnt++;
    if(!*pnt || *pnt != '=' || *pnt1)
      *newenvp++ = *envp;
  }
  *newenvp++ = *envp;
  return;
}

char * _dl_strdup(const char * string){
  char * retval;
  int len;

  len = _dl_strlen(string);
  retval = _dl_malloc(len + 1);
  _dl_strcpy(retval, string);
  return retval;
}

 

int _dl_interpreter_exit(int exitcode){
 
  return 0;
}



More information about the Gcc-bugs mailing list