"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