cygwinはglibcの夢をみるか


cygwinでの glibcのコンパイルに挑戦してみた。
動くものは出来てない。

用 意したもの glibc-2.3.3.tar.gz

[1]ソースの準備
(1) Makeconfig Makerules の .oS を.otに全ておきかえ
(2)i386-pc-noneで configureするので sysdeps/standaloneをどかしてsysdeps/genericの内容を sysdeps/standaloneにコピー。
さらに ,iwordsize-32, eee754, eee754/dbl-64, eee754/flt-32, eee754/ldbl-96, i386, i386/fpu の内容を上書きコピー  
(3) sysdeps/standalone/bits/errorno.hはこんな感じに した。
[2]configure
$mkdir build
$cd build
$../configure  --without-xcoff --without-elf --without-__thread --build=i386-pc-none --prefix=/opt/glibc
pc-nomeはarm-cpuしか受け付けな いみたいなんでconfigureをいじる。

[3]make

<bits/wordsize>
bits/wordsize に#define __WORDSIZE    32とやる
locale/loadarchive.c

<bits/fcntl.h>
O_LARGEFILE がみつからないというのでbits/fcntl.hで
#ifdef __USE_LARGEFILE64
# define O_LARGEFILE    0100000
#endif
#ifdef __USE_LARGEFILE64
struct flock64
  {
    short int l_type;    /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK.    */
    short int l_whence;    /* Where `l_start' is relative to (like `lseek').  */
    __off64_t l_start;    /* Offset where the lock begins.  */
    __off64_t l_len;    /* Size of the locked area; zero means until EOF.  */
    __pid_t l_pid;    /* Process holding the lock.  */
  };
#endif
みたいや る。
<sysdep.h>
アセンブラのENDマクロでこけるのでsysdep.h の先頭で
#define HAVE_CPP_ASM_DEBUGINFO
を定義する。
(こ れはどういう副作用があるかわかってない)

<add_n.S>
マ クロ     ALIGN (3) でこけちゃうので
standalne/xxxx.Sを全て削除した。


<tempname.c>
33: error: number of arguments doesn't match prototypeらしいので変数int __try_tempdirをたしておく。

<siglist.c>
siglist.h でSIGTRAP SIGBUS SIGURG SIGIO SIGXCPU SIGXFSZ SIGVTALRM SIGPROF SIGWINCH  SIGUSR1 SIGUSR2 等がみつからない。
include/sygnal.hの定義をbits/sygnum.hにコピー して元の定義をコメントアウトする。
#define    _NSIG    132
#define    SIGIOT  SIGABRT    /* IOT instruction, abort() on a PDP11 */
もたしておく

<dirstream.h>
dirstream.h:27:2: #error "No system-dependent definition of `struct __dirstream'.らしい。
the data type of  directory stream objects returned by `opendir ってあるからcygwinのdirentのDIRってやつだな。
typedef long _off_t;
#include <bits/types.h> //for __ino64_t;
( __dirstremの定義)

<uname.c>
UNAME_SYSNAME 等がみつからないconfig-name.hというファイルを作って定義してみる。
#define    _UTSNAME_LENGTH    1024
#define    UNAME_SYSNAME CYGWIN_NT-5.0
#define UNAME_RELEASE 1.5.19(0.150/4/2)
#define 2006-01-20 13:28
#define UNAME_MACHINE i686

<sysconf.c>
sysconf.c:147: error: `NSS_BUFLEN_GROUP' undeclared (first use in this function)
sysconf.c:150: error: `NSS_BUFLEN_PASSWD' undeclared (firs t use in this function)
grp/grp.h によれば
# ifdef __USE_MISC
/* Reasonable value for the buffer sized used in the reentrant
   functions below.  But better use `sysconf'.  */
#  define NSS_BUFLEN_GROUP    1024
# endif
pwd/pwd.hによれば
# ifdef __USE_MISC
/* Reasonable value for the buffer sized used in the reentrant
   functions below.  But better use `sysconf'.  */
#  define NSS_BUFLEN_PASSWD    1024
# endif
gccだったので__USE_MISCがONにならなかったのかな。。。。
sysconf.cの最初 にこの2行を加える。

<utime.c>
utime.c:30: error: `NULL' undeclared (first use in this function)
らしいので #define NULL 0 としておく

<nsswitch.c>
nsswitch.c:38:28: gnu/lib-names.h: No such file or directory
nsswitch.c:78: error: `LIBNSS_FILES_SO' undeclared here (not in a function)
unix \sysv\aix\のib-names.hが使えそうなのでstandalone/gnu/lib-names.hにおいてみる。

<aio_fsync.c:>
aio_fsync.c:37: error: `O_SYNC' undeclared (first use in this function)
 error: `O_DSYNC' undeclared (first use in this function)
O_SYNCはcygwin のfcntl.hにあるみたいだがO_DSYNCはない。
うーん。。 とりあえず。
if (op != O_SYNC && op != O_DSYNC) -> if(1)   とやってみる。

<clock_nanosleep.c>
clock_nanosleep.c:25: error: parse error before "clock_id"
clock_nanosleep.c:32: error: `TIMER_ABSTIME' undeclared (first use in this function)
cygwin によると
#define    _CLOCK_T_    unsigned long        /* clock() */
#define _CLOCKID_T_     unsigned long

#ifndef __clock_t_defined
typedef _CLOCK_T_ clock_t;
#define __clock_t_defined
#endif
#ifndef __clockid_t_defined
typedef _CLOCKID_T_ clockid_t;
#define __clockid_t_defined
#endif

#define TIMER_ABSTIME    4
だから bits/time.hの後 ろにたしておく。

<start.c>
/* This file should define the low-level program entry point,
   which should set up `__environ', and then do:
     __libc_init(argc, argv, __environ);
     exit(main(argc, argv, __environ));

:extern void __libc_init (int argc, char **argv, char **envp);
あれこれ書き換えないといけない。sysdeps/unix/start.cに変えてみた

コンパイルは通った!!

が。。。。しか し。。。。。。
なんかコンパイルしようとすると undefined referenceの嵐になる。。。。
cygwin との接続部分をかかないといけないのかなぁ。。。。

たるいから今日はねる。


[4] ハック&ハック
とりあえず 手元のプログラムをコンパイルしてみたら
multiple definitions of _environがでて
あと
___libc_init
_powerof2
__dl_mcount_wrapper_check
__sys_nerr_internal
__sys_errlist_internal
___libc_open
__IO_acquire_lock
__IO_release_lock
___libc_dlopen_mode
___libc_dlsym
___libc_dlclose
が みつからないらしい。

(0)multiple definitions of environ
<posix/unistd.h>
の473行目あたりに #define environ glibc_environ を足す
#define environ glibc_environ
#ifdef __USE_GNU
extern char **environ;
#endif

(1)___libc_init
extern void __libc_init (int argc, char **argv, char **envp);
らしい
(link.c)
void __libc_init (int argc, char **argv, char **envp){};
みたいなファイルをかいて link.oをlibc.aといっしょにリンクすることにした。

(2)_powerof2
../sysdeps/mach/hurd/sys/param.h:#define powerof2(x)    ((((x)-1)&(x))==0)
てのがあるから これを採用
<../sysdeps/standalone/sys/param.h>の最後に足した。

(3)__dl_mcount_wrapper_check
<standalone/bits/dlfcn.h>
#ifdef __USE_GNU
/* To support profiling of shared objects it is a good idea to call
   the function found using `dlsym' using the following macro since
   these calls do not use the PLT.  But this would mean the dynamic
   loader has no chance to find out when the function is called.  The
   macro applies the necessary magic so that profiling is possible.
   Rewrite
        foo = (*fctp) (arg1, arg2);
   into
        foo = DL_CALL_FCT (fctp, (arg1, arg2));
*/
# define DL_CALL_FCT(fctp, args) \
  (_dl_mcount_wrapper_check ((void *) (fctp)), (*(fctp)) args)

__BEGIN_DECLS

/* This function calls the profiling functions.  */
extern void _dl_mcount_wrapper_check (void *__selfpc) __THROW;

__END_DECLS

#endif
ほおほぉ ってことは
# define DL_CALL_FCT(fctp, args)  ((*fctp) args)
でいいんだべな。

(4)__sys_nerr_internal
(5)__sys_errlist_internal
cygwinのsys/errorno.hに定義があったので
<bits/sys_errlist.h>に
extern  const char * const sys_errlist[];
extern  int sys_nerr;
とかいて
#define _sys_errlist_internal sys_errlist
#define _sys_nerr_internal sys_nerr
を足してみた

(6)___libc_open
<../sysdeps/standalone/not-cancel.h>
#define open_not_cancel(name, flags, mode) \
  __libc_open (name, flags, mode)
#define open_not_cancel_2(name, flags) \
  __libc_open (name, flags)
とあるから __libc_open->_open と書き換えればいいかな。

(7)__IO_acquire_lock
(8)__IO_release_lock
ロック処理は多分windowsがやるので
<libio/libioP.h>の最後で
#define _IO_acquire_lock(a)
#define _IO_release_lock(a)
することにした。

(9)___libc_dlopen_mode
(10)___libc_dlsym
(11)___libc_dlclose
<include/dlfcn.h>に
extern void *__libc_dlopen_mode  (__const char *__name, int __mode);
extern void *__libc_dlsym   (void *__map, __const char *__name);
extern int   __libc_dlclose (void *__map);
とある
これは
#define __libc_dlopen_mode(a,b)   dlopen(a,b)
#define __libc_dlsym(a,b)        dlsym(a, b)
#define __libc_dlclose(a)        dlclose(a)
でいいか。

さて いくぞ!!
Segmentation fault (core dumped) 。。。。。がく

今日は この辺でゆるしといたる! 明日があると思うな!

さぁ今日こそいくぞ!
イニシャライズでこけてるみたいだなぁ。。。
とりあえずsetjmpはcygwinのを使わないとだめだろうから setjump.cをはずしてみよう。。。。。だめか。。

malloc.oをはずしてみたら Segmentation fault  しなくなった
でも 何も表示しない。。。。

だめぽーー


戻る



このHPの内容に問題等 ありましたらsけいし(skeishi@yahoo.co.jp)までメールを下さい。

sけいし発HP

[PR]AEdɂoH:ݐ肢œ౯