
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)までメールを下さい。
