BBSˮľÇ廪վ¡Ã¾«»ªÇø
·¢ÐÅÈË: dfbb (ÕÔÎÞ¼É), ÐÅÇø: Linux
±ê Ìâ: [CLDP]Gcc-Howto
·¢ÐÅÕ¾: BBS ˮľÇ廪վ (Sun May 3 08:53:59 1998)
The Linux GCC HOWTOÖÐÒë°æV0.1
×÷Õß: Daniel Barlow <dan@detached.demon.co.uk>
ÒëÕß: ³Â½¨Ñ«(Frank J.S. Chen)<frank63@ms5.hinet.net>
v1.17, 28 February 1996
_________________________________________________________________
ÕâÆªÎļþµÄÄÚÈݰüÀ¨ÁËÈçºÎÔÚLinuxÏÂÆôÓÃ(set up)GNU
CµÄ±àÒëÆ÷(compiler)ÒÔ¼°Ôõ÷ὨÁ¢(set
up)ÄÇЩ¿ÉÒÔÄÃÀ´¿ª·¢ÈíÌåµÄ³Ìʽ¿â(libraries);ͬʱ,
¶Ôì¶³ÌʽÂëµÄ±àÒë(compiling),Á¬½á(linking),Ö´ÐÐ(running)Óë³ý´í(debuggin
g)µÈµÈ,Ò²»áÓиŹÛ(overview)µÄ˵Ã÷.ÕâÆªÎļþд×÷µÄ²ÄÁÏ,Ì©°ëÊÇÀ´×Ôì¶Mitch
D'SouzaËùÊÕ¼¯GCC-FAQ,¶øÕâÆªÎļþÈ¡´úÁËGCC-FAQ.ÁíÍâÒ»¸öÀ´Ô´¾ÍÊÇELF-HOWTO
ÁË;¿ÉÒÔÕâ÷á˵,Linux GCC-HOWTO¿ìÒªÓÀ¾ÃµÄÈ¡´úELF-HOWTO,
³ÉΪGCC×îÖ÷ÒªµÄ˵Ã÷ÎļþÁË.
ÕâÊǵÚÒ»·Ý¹«¿ª·¢Ðеİ汾(²»ÐëÀí»á°æ±¾ÐòºÅ;ÄÇÊÇRCSµÄ½Ü×÷(artifact)).ÓÐÈ
κÎÖ¸ÕýÓ뽨ÒéµÄ,ÎÒ¶¼ºÜ»¶Ó.
_________________________________________________________________
~~~GCC HOWTOÖÐÒë°æËµÃ÷Îļþ V0.1 ²¹³ä˵Ã÷ Taipei, Taiwan, R.O.C.
1. Õâ·ÝÒëÎÄΪLinux document projects(LDP)ÖÐÎÄ·Òë¼Æ»
ϵÁÐÖ®Ò».Ä¿Ç°Ö®ÍøÖ·Îªhttp://www.linux.org.tw/CLDP/.»¶Ó
¸÷Î»ÍøÓÑӻԾͶÈë´ËÒ»¼Æ».
2. ÎÒ²¢Ã»ÓÐÍêÈ«°´ÕÕÔÎÄÖð×Ö·
Òë.ΪÁËÁ¦ÇóÒëÎÄͨ³©¿É¶Á,ÎÒ»áÉÔÉÔµÄÖØ×éÒ»²¿·ÝµÄÎÄ×Ö,¼ÓÓÍÌí´×,»òÊǾ«
¼òÔ
ÎÄ;ÕâÑù×öµÄ»°,¿ÉÒÔÃÖ²¹ÖÐÓ¢ÎļäÓï·¨½á¹¹µÄ²îÒìÐÔ,ÇÒÓïÆø¿ÉÒÔ¹áͨÎÞ°.
3. һЩ¹Ø¼ü×ÖÓëרҵ´Ê»ãµÈ,»á¸½¼ÓÉÏÔÎĵ¥×Ö.
4. ÓöÓÐתÒëÀ§ÄÑ,ΨÔÎij£¼ûµÄ×Ö»ã,Èçbugs,shadow
password,paddingÖ®ÀàµÄ,Ôò±£ÁôÔ
ÎIJ»±ä.Èô¸ó϶ÔÕâЩ×Ö»ãÓÐÊʵ±Òë´ÇµÄ,Çë²»ÁßÖ¸½Ì.
5. ÄÚÎÄÖÐÈôÓöÓÐ"[ÒëÕß×¢:**]"Ö®±ê¼Ç,ÔòΪ±¾È˶îÍâÖ®×¢½â.
6. ¶ÔÕâÆªÒëÎÄÓÐÈκν¨ÒéÓëÒÉÎʵÄ,ÇëemailÖÁfrank63@ms5.hinet.net.
7. WWW Home Page: http://wwwhome.fancy.com.tw/~frank/.
8. ´ËÖÐÒëÎļþÖ®·ÒëȨÒÑÈ¡µÃÓ¢¼®Ö®Ô×÷ÕßDaniel Barlow
ÏÈÉú֮ͬÒâ;Áí,³Â½¨Ñ«ÏÈÉú±£Óд˷ÝÖÐÒë°æÎļþËùÓеÄȨÀû,Äã¿ÉÒÔÈÎÒâµÄ¿
½±´,ÒÔ¸÷ÖÖýÌå'ÍêÕû'É¢²¼Õâ·ÝÖÐÒëÎļþ,Ψ´Ë²¹³ä˵Ã÷ÐèÔ
·â²»¶¯¸½ÉÏ,ÇÒ²»¿ÉÈÎÒâ¸ü¶¯ÒëÎÄ.
9. ·ÒëÆðʼÈÕÆÚΪ:11/7/97;½ØÖ¹ÈÕÆÚΪ:11/19/97
1. Éú»ðÉÏ·(Preliminaries)!
1.1. ELF vs. a.out
1.2. ×÷ÕßµÄ˽Óï(Administrata)
1.3. Ó¡Ë¢ÓëÅŰæ(typography)
2. ÉÏÄÄ×¥ÕâЩ¶«¶«?
2.1. Õâ·ÝÎļþ×ùÂäÖ®´¦
2.2. ÆäËüÏà¹ØµÄ˵Ã÷Îļþ
2.3. GCC
2.4. C³Ìʽ¿âÓë±êÍ·µµ
2.5. Ïà¹ØÁªµÄ¹¤¾ß (as, ld, ar, strings etc)
3. GCCµÄ°²×°(installation)ÓëÆôÓÃ(setup)
3.1. GCCµÄ°æ±¾
3.2. ¶«¶«×°ºÃáá¶¼µ½ÄĶùÈ¥ÁË?
3.3. ±êÍ·µµ¨Ë¨ß?±êÍ·µµ¨Ë¨ß?
3.4. ½¨Á¢½»²æ±àÒëÆ÷(Building cross compilers)
4. ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
4.1. gcc×ÔÐж¨ÒåµÄ·ûºÅ
4.2. ÏßÉÏÇóÖú˵Ã÷(invocation)
4.3. ÒÆÖ²ÄÜÁ¦(Portability)
5. Debugging and Profiling
5.1. Preventative maintenance (lint)
5.2. ³ý´í(Debugging)
5.3. ÅÔÇòà»÷(Profiling)
6. Á¬½á(Linking)
6.1. ¹²Ïí³Ìʽ¿â vs¾²Ì¬³Ìʽ¿â
6.2. Interrogating libraries (`which library is sin() in?')
6.3. Xµµ°¸???
6.4. ½¨Á¢Äã×Ô¼ºµÄ³Ìʽ¿â(Building your own libraries)
7. ¶¯Ì¬ÔØÈë(Dynamic Loading)
7.1. »ù±¾¸ÅÄî
7.2. ´íÎóѶϢ(Error messages)
7.3. ¿ØÖƶ¯Ì¬ÔØÈëÆ÷µÄÔË×÷
7.4. ÒÔ¶¯Ì¬ÔØÈë׫д³Ìʽ
8. Óë·¢Õ¹ÈËÊ¿ÁªÂç
8.1. Bug±¨±í
8.2. ÐÖú·¢Õ¹
9. ½áÓï
9.1. ÃûÈ˰ñ
9.2. ·Òë
9.3. »¶ÓÈκεĻØÀ¡(Feedback)
9.4. ºÏ·¨µÄÐÐåɹ涨
10. Ë÷Òý
The Linux GCC HOWTOÖÐÒë°æV0.1 : Éú»ðÉÏ·(Preliminaries)!
Previous: The Linux GCC HOWTOÖÐÒë°æV0.1
Next: ÉÏÄÄ×¥ÕâЩ¶«¶«?
_________________________________________________________________
1. Éú»ðÉÏ·(Preliminaries)!
1.1. ELF vs. a.out
Ŀǰ,LinuxµÄ·¢Õ¹Õý²¨ÌÎÐÚÓ¿µÄ½øÐÐÖø.¼òµ¥Ò»µã½²,LinuxÓÐÁ½ÖÖÖ´ÐеµµÄ¸ñʽ(
formats)¿ÉÓÃ,È¡¾öì¶ÄãµÄϵͳÊÇÔõ÷áÕûºÏÆðÀ´µÄ;Äã¿ÉÄÜÁ½ÖÖ¶¼ÓÐ.¶ÁÁËÕâ·ÝÎļ
þÖ®áá,Äã¾Í»áÖªµÀÊÇÄÇÒ»ÖÖÁË.
ÄÇ,ÒªÔõ÷áÇø±ðÄØ?Ö´Ðй«ÓóÌʽ(utility)'file' (ÀýÈç,file
/bin/bash)¾Í¶ÔÁË.¾ÍELF¸ñʽµÄ³ÌʽÂëÀ´½²,ÏÔʾ³öÀ´µÄѶϢ»áº¬ÓÐELFµÄ×ÖÑÛ;È
ç¹ûÊÇa.out¸ñʽµÄ,ѶϢÄھͻáóéÓÐ Linux/i386µÄ×ÖÑùÁË.
ELFÓëa.out¸ñʽµÄ²îÒìÖ®´¦,»áÔÚááÐøµÄÕ½ÚÖÐÌÖÂÛ(ºÜ¹ã·ºà¸).ELFÊDZȽÏеĸ
ñʽ,Ò»°ã¶øÑÔ,½ÓÊܵij̶ȽϼÑ.
1.2. ×÷ÕßµÄ˽Óï(Administrata)
°æÈ¨ËµÃ÷(copyright
information)ÓëºÏ·¨µÄÐÐåɹ涨(legalese),¾Í°ÚÔÚÕâ·ÝÎļþµÄβ¶Ë.³ý´ËÖ®Íâ,Î
Ò......,ÎÒ»¹ÓÐһЩ²»µÃ²»ÌáÐÑÄãµÄ»°Òª½²:¾ÍËãÄã¡õÖøÃ»Ê¸É,Ò²²»ÒªÔÚUsenet
É϶ªÒ»Ð©´ô¹ÏÎʵÄÎÊÌâ;»¹Óа¡,²»ÒªÀÏÒÔΪ×Ô¼ºCµÄ¹¦Á¦Éîºñ,רÃÅ·¢±íһЩ²»ÊÇ
bugsµÄbugs³öÀ´¶ªÈËÏÖÑÛ,
¸æËß±ðÈËÄ㲻ѧÎÞÊõ.×îáá;½À¿ÚÏãÌǵÄʱºò,²»·ÁÍÚÍÚÄãµÄ±Ç¿×(,and picking
your nose while chewing gum)! [ÒëÕß×¢:²»ÖªµÀÕâÊÇÄÇÒ»¹úµÄÓÄĬ? eh?
:-)ÁíÒ»ÖÖ¿ÉÄÜÊÇÔÎÄÓÐȱ©×Ö»ã, ÏñÊÇ"and not picking your nose while
chewing gum."]
1.3. Ó¡Ë¢ÓëÅŰæ(typography)
Èç¹ûÄãÏÖÔÚ¶ÁµÄÊÇPostscript,dvi»òÕßÊÇhtml¸ñʽµÄ»°,ÄÇ÷áÄãËù¿´µ½µÄ×ÖÐͱä»
¯¾Í»á±ÈÖ»¶Á´¿ÎÄ×Ö¸ñʽµÄÈ˶àһЩ.ÌØ±ðµÄÊÇ,µµ°¸Ãû³Æ(filenames),ÃüÁî(comm
ands),ÃüÁîµÄÊä³ö(command output)Óëժ¼³öÀ´µÄÔʼÂë(source
code)µÈ,ͳͳ¶¼ÊÇ´ò×Ö»úµÄ×ÖÐÍÑùʽ(form).ÕâÑù×öµÄ»°,¶Ôì¶Ä³Ð©ÐèҪǿµ÷µÄ±ä
Êý(variables)ÒÔ¼°Ã»ÓÐÌØ¶¨½á¹ûµÄ¡õÀý(random
things)¶øÑÔ,¾Í¿ÉÒԴﵽǿµ÷µÄЧ¹ûÁË.
¶ÁÕâ·ÝÎļþµÄͬʱ,ÄãÒ²»áµÃµ½Ò»¸öÓÐÓõÄ(usable)Ë÷Òý(index).¼ÙÈôÊÇdvi,
postscriptÖ®ÀàµÄ°æ±¾,Ë÷ÒýµÄÊý×Ö¾ÍÊÇÕ½Ú(section)µÄ±àºÅ;Èç¹ûÊÇHTMLµÄ»°,
ÕâЩÊý×ֻᰴ˳ÐòÅÅÁÐ,Äã¿ÉÒÔÓû¬Êó×ó¼üÀ´Á¬½á(linking)Ïà¶ÔµÄË÷Òý;Èç¹ûÄã¿
´µÄÊÇ´¿(plain)ÎÄ×Ö°æ±¾µÄ»°, Êý×Ö¾ÍÖ»ÊÇÊý×Ö,
û±ðµÄº¬Òâ;½¨ÒéÄã¸Ï¿ìÉý¼¶ÎªÃîÁ¨!
ÎÒËùÓõÄshellÊÇBourne shell(²»ÊÇC shell),¾ÙµÄÀý×Ó×ÔÈ»ÊÇBourne
shellµÄÓï·¨.Èç¹ûÄãÓõÄÊÇC shellµÄ»°, »·¾³±äÊýÉ趨µÄÓï·¨»áÏñÏÂÃæÕâÑù:
% setenv FOO bar
ÒªÊÇÓÃBourne shellµÄ»°, ÎÒ»áÕâÑù×Óд:
$ FOO=bar; export FOO
Èç¹ûÌáʾ·ûºÅ(prompt)ÏÔʾµÄÊǾ®×Ö·ûºÅ#,¶ø²»ÊÇÇ®×Ö·ûºÅ
$,ÄÇ÷á,ºÜÓпÉÄÜÊÇÕâ¸öÃüÁîÖ»ÊÊÓÃroot¶øÒÑ.µ±È»À²!ÒªÊÇÄãÊÔÁËÕâЩ¡õÀý,½á¹û
ŪµÃÄãµÄϵͳ·¢ÉúÔÖ±ä,ÎÒ¿ÉÊÇÒ»µãÔðÈÎÒ²²»»á¸ºµÄà¸!×£ÄãÐÄÇéºÃ°¡!:-)
[ÒëÕß×¢:Ç£ÍÏ(ÃöÄÏÓï) _ .]
11/8/97Òë.
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : Éú»ðÉÏ·(Preliminaries)!
Previous: The Linux GCC HOWTOÖÐÒë°æV0.1
Next: ÉÏÄÄ×¥ÕâЩ¶«¶«? The Linux GCC HOWTOÖÐÒë°æV0.1 : ÉÏÄÄ×¥ÕâЩ¶«¶«?
Previous: Éú»ðÉÏ·(Preliminaries)!
Next: GCCµÄ°²×°(installation)ÓëÆôÓÃ(setup)
_________________________________________________________________
2. ÉÏÄÄ×¥ÕâЩ¶«¶«?
2.1. Õâ·ÝÎļþ×ùÂäÖ®´¦
Õâ·ÝÎļþÊÇLinux HOWTOϵÁÐÖ®Ò».Ò×ÑÔÖ®,Äã¿ÉÒÔÔÚËùÓдæ·ÅLinux
HOWTOÎļþµÄÍøÕ¾ÉÏÃæÕÒµ½ËüµÄ·¼×Ù,Àý
Èçhttp://sunsite.unc.edu/pub/linux/docs/HOWTO/.HTML¸ñʽµÄ°æ±¾(¿ÉÄÜ»áÊÇ
½Ïеİ汾)¿ÉÒÔ´Óhttp://ftp.linux.org.uk/~barlow/howto/gcc-howto.htmlÉ
ÏÃæ×¥ÏÂÀ´.
2.2. ÆäËüÏà¹ØµÄ˵Ã÷Îļþ
gccÕýʽµÄ˵Ã÷ÎļþÊǸ½ÔÚ·¢ÐеÄÔʼÂë(source
distribution)ÄÚ(ÍùÏ¿´¾ÍÓÐÁË!),ÀïÍ·ÓÐtextinfoÓë.infoÁ½ÖÖµµ°¸.ÒªÊÇÄãµÄÍ
øÂ·Á¬½ÓËÙÂʹ»¿ì,»òÕßÊÇÓÐһƬcdrom;²»È»µÄ»°,Óи߶ȵÄÄÍÐÄÒ²³É,Äã¿ÉÒÔ×Ô¼º
°ÑËüuntar,È»ááÔÙ°ÑÏà¶ÔÓ¦µÄλԪһһ¿½±´µ½/usr/infoµÄĿ¼µ×ÏÂ.¼ÙÈçÄãµÄÌõ
¼þÓëÉÏÊöµÄ²»·û,²»·Áµ½
tsx-11Õ¾ÉÏÈ¥ÕÒÒ»ÕÒ.²»¹ý,ÎÒÏë,ûÓбØÒªÀÏÊǵë¼ÇÖø×îеİ汾°É.
libcµÄÎļþ˵Ã÷ÓÐÁ½ÖÖÀ´Ô´.Ò»ÖÖÊÇGNU
libc,ÒÔ.infoµÄ¸ñʽ´¢´æ,³ýÁËstdioÖ®Íâ,ÆäâÅLinux
libcµÄ˵Ã÷¶¼Ï൱Ï꾡¾«È·.ÁíÒ»ÖÖ¿ÉÒÔÔÚLinuxµÄarchivemanpages
ÉÏÕÒµ½ÏµÍ³ºô½Ð(system
call)(µÚ2½Ú)Óëlibcº¯Êý(function)(µÚ3½Ú)µÄÎļþ˵Ã÷.
2.3. GCC
½â´ðÓжþ:
(a)Äã¿ÉÒÔÔÚftp://tsx-11.mit.edu:/pub/linux/packages/GCC/µÄÍøÕ¾ÉÏÕÒµ½
ÕýʽµÄLinux
GCC·¢ÐÐϵͳ(distribution),ÇÒÒѱàÒëºÃµÄ(read-compiled)¿ÉÖ´Ðеµ(in
binary).µ±ÎÒÔÚдÕâ·ÝÎļþʱ,2.7.2(gcc-2.7.2.bin.tar.gz)ÊÇ×îеİ汾.
(b)×ÔÓÉÈíÌå»ù½ð»á(Free Software Foundation)Ëù·¢²¼µÄGCC×îÐÂÔ
ʼÂë¿ÉÒÔ´ÓÍøÕ¾GNU
archivesÉÏÈ¡µÃ.ûÓбØÒª·ÇµÃÓëÉÏÊöµÄ°æ±¾Ò»Ö²ÅÐÐ,²»¹ýÕâ¸ö°æ±¾µÄÈ·ÊÇĿǰ
×îеÄ.Linux
GCCµÄά»¤ÈËÊ¿(maintainers)ÈÃÄã¿ÉÒÔºÜÇáËɵÄ×ÔÐбàÒëÕâ¸ö×îеİ汾.confi
gureÃüÁî¸å(script)»á°ïÄã×Ô¶¯½¨ºÃ(set it all
up)ËùÓиÃ×öµÄÊÂ.½¨ÒéÄãÓпղ»·Áµ½tsx-11¿´¿´,˵²»¶¨»áÓÐÐÞÕýµÄ°æ±¾(patche
s)ÊÇÄã»áÏëÒªÓõÄ(apply).
Èç¹ûÏëÒª±àÒë³öһЩÓÐÓõĶ«¶«(non-trivial)(²»ÊÇÎÒÂÞËô,»¹ÊÇÓв»ÉÙϸËöµÄ¶
«¶«ÔÚÁ¨!),ÏÂÃæÒ»Ð¡½ÚËù̸µÄÒ²ÊÇÄãÒª¾ß±¸µÄ:
2.4. C³Ìʽ¿âÓë±êÍ·µµ
ÔÚÕâ¶ùÄã¸ÃÑ¡µÄÊÇÈ¡¾öì¶(i)ÄãµÄϵͳÊÇELFÒà»òÊÇa.outµÄ;(ii)ÄãÏ£ÍûÄãµÄϵ
ͳ±ä³ÉÄÄÒ»ÖÖ?Èç¹ûÄãÊÇ´Ólibc 4Éý¼¶µ½libc
5,ÄÇ÷á¸øÄãÒ»¸öÁ¼ÐĵĽ¨Òé,È¥¿´¿´ELF-HOWTOÎļþ.ÄãÒ»¶¨»áÎÊ,ÔÚELFÎļþµÄÄĶ
ùÄØ?ºÙ!ºÙ!²»Æ«²»ÒÐ,¾Í²î²»¶à¸úÕâ·ÝÎļþÒ»ÑùµÄλÖÃ.Äã¿ÉÒÔÔÚÍøÕ¾tsx-11ÉÏÃæ
ÕÒµ½ÄãÏëÒªµÄ.
libc-5.2.18.bin.tar.gz
--- ELF¹²Ïí³Ìʽ¿â(ELF shared library images),¾²Ì¬³Ìʽ¿â(static
libraries)Óë±êÍ·µµ(include files)(Õë¶ÔCÓïÑÔÓëÊýѧ³Ìʽ¿âµÄ).
libc-5.2.18.tar.gz
---libc-5.2.18.bin.tar.gzµÄÔ
ʼÂë.ÕâÁ½¸öµµ°¸Äã¶¼ÐèÒª,.bin.Ì×¼þ(package)ÄÚº¬ÓбêÍ·µµ(header
files).Èç¹û´ËʱÄãÕýÓÌÔ¥²»¾ö,²»ÏþµÃÊÇÒªÀÏÉíÇ××ÔϺ£,¶¯ÊÖ±àÒëC³ÌÊ
½¿â;»¹ÊÇÖ±½ÓÓñàÒëºÃµÄ¶þ½øÎ»µµ(binaries)¾Í¿ÉÒÔÁË.ÓÐÕâÖÖÀ§ÈŵÄÈË
,À´,¿´ÎÒµÄ×ìÐÎ:ÓÃÈ˼ұàÒëºÃµÄ¶þ½øÎ»µµ²»¾Í½â¾öÁËÂï.Ö»ÓÐÔÚÄãÏëÒªN
YS»òÊÇshadow passwordµÄÇé¿öÏÂ,Äã²ÅÐèÒª×Ô¼ºµÄÊÖÀ´Íƶ¯ÊÇÖ¸³ö(indicates)ÄãĿǰÔÚÓõÄgccÊÇΪÁË486µÄ΢´¦ÀíÆ÷(processor)¶ø
дµÄ-¿ÉÄÜÄãµÄµçÄÔÊÇ386»òÕßÊÇ586.Õâ3ÖÖ΢´¦ÀíÆ÷µÄ¾§Æ¬(chips)Ëù±àÒë¶ø
³ÉµÄ³ÌʽÂë,±Ë´Ë¼äÊÇ¿ÉÒÔÏàÈÝʹÓõÄ.²î±ðÖ®´¦ÊÇ486µÄ³ÌʽÂëÔÚijЩµØ·½Ó
мÓÉÏpaddingµÄ¹¦ÄÜ,ËùÒÔ¿ÉÒÔÔÚ486ÉÏÃæÅܵñȽϿì.Õâ¶Ô386µÄ»úÆ÷¶øÑÔ,Ô
ÚÖ´ÐгÌʽµÄЧÄÜ(performance)Éϲ¢Ã»ÓÐʲ÷á²»Á¼µÄÓ°Ïì(detrimental
effect),Ö»²»¹ýÕæµÄ(does)»áÈóÌʽÂë±äµÃÉÔÉԵĴóÁËЩ.
* box.
Õâ¿ÉÒÔ˵һµãÒ²²»ÖØÒª;²»¹ýÒ²¿ÉÄÜÁíÓÐËùÖ¸(ÏñÊÇslackware»òÕßÊÇdebian)
,»òÕ߸ù±¾Ê²÷áÒ²²»ÊÇ(ËùÒÔÂÞ!ÍêÕûµÄĿ¼Ãû³ÆÊÇi486-linux).¼ÙÈçÄãÊÇʵ¼
ùÅɵĴú±í,Ç××Ô¶¯ÊÖ½¨Á¢Êôì¶×Ô¼ºµÄgcc,ÄÇ÷áÄã¿ÉÒÔÔÚ½¨Á¢µÄ¹ý³ÌÖÐ(build
time)É趨ÕâÒ»Ïî,ÒÔ×°µãÃÅÃæ(cosmetic effect).¾ÍÏñÎÒ×öµÄÒ»Ñù:-).
* linux.
ÆäʵÕâÊÇÖ¸linuxelf,»òÕßÊÇlinuxaout.ÕâÒ»µã»áÁîÈËÒýÆð²»±ØÒªµÄÀ§»ó,¾¿
¾¹ÊÇÖ¸ÄÄÒ»ÖÖ»á¸ù¾ÝÄãËùÓõİ汾¶øÒì.
+ linux
ÒâÖ¸ELFÈô°æ±¾ÐòºÅÊÇ2.7.0»òÊǸüеİ汾;·ñÔòµÄ»°,¾ÍÊÇa.outµÄÁË
.
+ linuxaout
ÒâÖ¸a.outµÄ¸ñʽ.µ±linuxµÄ¶¨Òå(definition)´Óa.out¸ü»»µ½ELFʱ,l
inuxaout¾Í»áË³Ë®ÍÆÖÛ,Ò¡ÉíÒ»±ä,³ÉÁËÒ»¸öÄ¿±êÎï¼þ(target).Òò´Ë,Ä
ã²»»á¿´µ½Èκΰ汾ÐÂì¶2.7.0µÄgccÓÐlinuxaout¸ñʽµÄ.
+ linuxelf ÒѾ
¹ýʱÁË.ͨ³£ÄÇÊÇÖ¸2.6.3°æµÄgcc,¶øÕâ¸ö°æ±¾Ò²¿ÉÓÃÀ´²úÉúELFµÄ¿ÉÖ´
Ðеµ(executables).ҪעÒâµÄÊÇ,gcc
2.6.3°æÔÚ²úÉúELF³ÌʽÂëʱ»áÓÐbugs-Èç¹ûÄãĿǰÓõÄÊÇÕâ¸ö°æ±¾,½¨Ò
éÄã¸Ï¿ìÉý¼¶.
* 2.7.2 °æ±¾µÄÐòºÅ.
ËùÒÔ,×ܽáÆðÀ´,ÎÒÓÐ2.7.2°æµÄgcc,¿ÉÒÔ²úÉúELF¸ñʽµÄ³ÌʽÂë.¾ÍÕâ÷á¼òµ¥,¾ªÑÈ
°É!eh?
3.2. ¶«¶«×°ºÃáá¶¼µ½ÄĶùÈ¥ÁË?
Èç¹û°²×°gccʱûÓÐ×ÐϸµÄ¿´ÖøÓ©Ä»,»òÕßÄãÊÇ´ÓÒ»¸öÍêÕûµÄ·¢ÐÐϵͳÄÚ°Ñgccµ¥¶
À×¥³öÀ´°²×°µÄ»°,ÄÇ÷áÒ²ÐíÄã»áÏëÖªµÀµ½µ×ÕâЩ¶«¶«×°ºÃááÊÇסÔÚÕû¸öµµ°¸ÏµÍ³
(file-system)µÄÄǸöµØ·½.¼¸¸öÖØµãÈçÏÂ:
* /usr/lib/gcc-lib/target/version/
(Óë×ÓĿ¼(sub-directories))´ó²¿·ÝµÄ±àÒëÆ÷(compilers)¾ÍÊÇסÔÚÕâ¶ùµÄ
.ÔÚÕâ¶ùÓпÉÖ´ÐеijÌʽ,ʵ¼ÊÔÚ×ö±àÒëµÄ¹¤×÷;ÁíÍâ,»¹ÓÐÒ»Ð©ÌØ¶¨°æ±¾µÄ(v
ersion-specific)³Ìʽ¿âÓë±êÍ·µµ(include files)µÈ.
* /usr/bin/gcc
Ö¸±àÒëÆ÷µÄÇý¶¯³Ìʽ(driver)--¾ÍÊÇÄãʵ¼ÊÔÚÃüÁîÁÐ(command
line)ÉÏÖ´ÐеijÌʽ.Õâ¸öĿ¼¿É¹©¸÷ÖÖ°æ±¾µÄgccʹÓÃ,Ö»ÒªÄãÓò»Í¬µÄ±àÒë
Æ÷Ŀ¼(ÈçÉÏËùÊö)À´°²×°¾Í¿ÉÒÔÁË.ÒªÖªµÀÄÚ¶¨µÄ°æ±¾ÊÇÄÇÒ»¸ö,ÔÚshellÌáÊ
¾·ûºÅÏ´ògcc -v.ÒªÊÇÏëÇ¿ÆÈÖ´ÐÐij¸ö°æ±¾,¾Í»»´ògcc -V version.ÀýÈç:
# gcc -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2
# gcc -V 2.6.3 -v
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.6.3/specs
gcc driver version 2.7.2 executing gcc version 2.6.3
* /usr/target/(bin|lib|include)/. Èç¹ûÄã×°ÁËÊýÖÖµÄÄ¿±êÎï¼þ(multiple
targets),ÀýÈça.outÓëelf,»òÕßijһÖֵĽ»²æ±àÒëÆ÷(cross-compiler)µÈµÈ
;ÄÇЩÊôì¶·ÇÖ÷Á÷Ä¿±êÎï¼þ(non-native target(s))µÄ³Ìʽ¿â,binutils(as,
ldµÈµÈ)¹¤¾ßÓë±êÍ·µµ(header
files)µÈ¶¼¿ÉÒÔÔÚÕâ¶ùÕÒµ½.¼´Ê¹ÄãÖ»°²×°ÁËÒ»ÖÖgcc,»¹ÊÇ¿ÉÒÔÔÚÕâ¶ùÕÒµ½Õ
âЩÔ
±¾¾ÍÊÇÌæËüÃÇ×¼±¸µÄ¶«¶«.Èç¹û²»ÊÇÔÚÕâ¶ù,ÄÇ÷á¾ÍÓ¦¸ÃÊÇÔÚ/usr/(bin|lib|
include)ÁË.
* /lib/,/usr/lib
ÓëÆäËüµÄĿ¼µÈ,¶¼ÊÇÖ÷Á÷ϵͳ(native-system)µÄ³Ìʽ¿âĿ¼.Ðí¶àµÄÓ¦Óó
Ìʽ¶¼»áÓõ½/lib/cpp
,Òò´ËÄãÒ²ÐèÒªËü---×÷·¨ÉÏ,²»ÊÇ´Ó/usr/lib/gcc-lib/target/version/
Ŀ¼À�±´,¾ÍÊÇŪ¸ö·ûºÅÁ¬½á(symlink)Ö¸ÏòÄǶù.
[ÒëÕß×¢:Ëùνnattoconf.hʱÊÇ'Many files depend on <linux/autoconf.h>,which
otherwise may not
exist,*'.´Ë´¦Ö®otherwiseÖ®´ÊÐÔӦΪÐÎÈÝ´Ê(adj),Ö¸'ÁíÒ»Çé¿ö','ÁíÒ»ÖÖ
','²»Í¬µÄ'Ö®Òâ,½«ÔÎÄÐÎÈÝ´Ê×Ó¾ä²ð¿ªÀ´Ó¦Îª: (i). Many files depend
on <linux/autoconf.h>. (ii).<linux/autoconf.h> of other condition
may not exist. ÓëÏÂÒ»¾ä»¥Ïà±È¶Ô,´Ë´¦Ó¦Í¬Ö¸ÔÚ²»Í¬°æ±¾Ö®Çé¿öÏÂ.]
ËùÒÔ,µ±ÄãÔÚĿ¼/usr/src/linuxµ×ÏÂ,½â¿ªºËÐĵijÌʽÂëʱ,¾ÍÕÕÖøÏÂÃæÖ¸Ê
¾µÄ×ö°É!
$ cd /usr/src/linux
$ su
# make config
[»Ø´ð½ÓÏÂÀ´µÄÎÊÌâ.ͨ³£»Ø´ðµÃÕý²»ÕýÈ·²¢²»ÖØÒª,³ý·ÇÄã´òËã¼ÌÐø¡õÆð(go on and build
)ÄãµÄºËÐÄ.]
# cd /usr/include
# ln -s ../src/linux/include/linux .
# ln -s ../src/linux/include/asm .
* ÖîÈç<float.h>, <limits.h>,<varargs.h>, <stdarg.h>
Óë<stddef.h>Ö®ÀàµÄµµ°¸,»áËæÖø²»Í¬µÄ±àÒëÆ÷°æ±¾¶øÒì,Êôì¶Äã×Ô¼º'¸öÈË'
µÄµµ°¸,¿ÉÒÔÔÚ
/usr/lib/gcc-lib/i486-box-linux/2.7.2/include/ÓëÆäËüÓÐÏàÀàËÆ(Ïàͬ)
Ŀ¼Ãû³ÆµÄµØ·½(places of that ilk)ÕÒµ½. 11/11/97Òë
3.4. ½¨Á¢½»²æ±àÒëÆ÷(Building cross compilers)
3.4.1. ½«Linuxµ±×÷Ä¿±ê×÷ҵƽ̨(target platform)
¼ÙÉèÄãÒѾÄõ½gccµÄÔʼÂë,ͨ³£ÄãÖ»ÒªÒÀÑINSTALLµµÄÚµÄָʾ±ã¿ÉÒ»ÇÐok.
makeááÃæð¤¸öconfigure --target=i486-linux --host=XXX on platform
XXX,¾ÍÄܰïÄã±ä°ÑÏ·ÁË(do the
trick).ҪעÒâµÄÊÇ,Äã»áÐèÒªLinuxÓëºËÐĵıêÍ·µµµÄ;¶øÇÒÄãÒ²ÐèÒª½¨Á¢½»²æ×é
ÒëÆ÷(cross assembler)Óë½»²æÁ¬½áÆ÷(cross
linker),À´Ô´ÊÇftp://tsx-11.mit.edu/pub/linux/packages/GCC/
3.4.2. Linuxµ±³ÉÀ´Ô´×÷ҵƽ̨(source platform),MSDOS×÷ΪĿ±ê×÷ҵƽ̨
Ugh.ºÜÃ÷ÏÔµÄ,Õâ¸ö´ó¸ÅÐèÒªÓõ½"emx"Ì×¼þ(package)»òÕßÊÇ"go"ÑÓÉìÌ×¼þ(exte
nder).Çë×ÔÐÐÈ¥ftp://sunsite.unc.edu/pub/Linux/devel/msdos¿´¿´.ÎÒ²¢Ã»ÓÐ
²âÊÔ¹ýÕâ¸ö,Òò´ËÒ²ÎÞ·¨±£Ö¤(vouch)ËüµÄ¹¦ÄÜ(abilities).
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : GCCµÄ°²×°(installation)ÓëÆôÓÃ(setup)
Previous: ÉÏÄÄ×¥ÕâЩ¶«¶«?
Next: ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ The Linux GCC HOWTOÖÐÒë°æV0.1
: ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
Previous: GCCµÄ°²×°(installation)ÓëÆôÓÃ(setup)
Next: Debugging and Profiling
_________________________________________________________________
4. ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
4.1. gcc×ÔÐж¨ÒåµÄ·ûºÅ
Ö»ÒªÖ´ÐÐgccʱ,¸½¼Ó
-vÕâ¸ö²ÎÊý(switch),¾ÍÄÜÕÒ³öÄãËùÓõÄÕâ°ægcc,×Ô¶¯°ïÄ㶨ÒåÁËʲ÷á·ûºÅ(symb
ols).ÀýÈç,ÎҵĻúÆ÷¿´ÆðÀ´»áÏñÕâÑù:
$ echo 'main(){printf("hello world\n");}' | gcc -E -v -
Reading specs from /usr/lib/gcc-lib/i486-box-linux/2.7.2/specs
gcc version 2.7.2
/usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v -undef
-D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix -Di386 -Dlinux
-D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix -D__i386
-D__linux -Asystem(unix) -Asystem(posix) -Acpu(i386)
-Amachine(i386) -D__i486__ -
¼ÙÈôĿǰÄãÕýÔÚдµÄ³ÌʽÂë,»áÓõ½Ò»Ð©Linux¶ÀÓеÄÌØÐÔ(Linux-specific
features),ÄÇ÷á°ÑÄÇЩÎÞ·¨ÒÆÖ²µÄ³ÌʽÂë(non-portable
bits),ÒÔÌõ¼þʽ±àÒë(conditional compilation)µÄǰÖÃÃüÁî·âÀ¨(enclose
in)ÆðÀ´,¿ÉÊǸö²»´íµÄÖ÷ÒâÄØ!
#ifdef __linux__
/* ... funky stuff ... */
#endif /* linux */
ÓÃ__linux__¼´¿É´ï³ÉÄ¿µÄ;¿´×Ðϸһµã,²»ÊÇlinux°¡.½ö¹ÜááÕßÒ²Óж¨Òå,±Ï¾¹,È
ÔÈ»²»ÊÇPOSIXµÄ±ê×¼(not POSIX compliant).
4.2. ÏßÉÏÇóÖú˵Ã÷(invocation)
gcc±àÒëÆ÷²ÎÊý(switches)µÄ˵Ã÷ÎļþÊÇgcc info page(ÔÚEmacsÄÚ,°´ÏÂC-h
i,È»ááÑ¡'gcc'µÄÑ¡Ïî).ÒªÊÇŪ²»³öÀ´,²»ÊÇÂôÄãCD-ROMµÄÈË,û°ÑÕâ¸ö¶«¶«Ñ¹¸øÄ
ã,²»È»¾ÍÊÇÄãÏÖÔÚÓõÄÊǾɰæµÄ.ÕâÖÖÇé¿öÏÂ,×îºÃµÄ·½·¨ÊÇÒÆ¶¯×ðÍε½archivef
tp://prep.ai.mit.edu/pub/gnu»òÊÇËüµÄmirrorsվ̨ÉÏ,°ÑgccµÄÔ
ʼµµ°¸×¥»Ø¼Ò,ÖØÐÂÅëâ¿Ò»·¬.
gcc manual page (gcc.1) ¿ÉÒÔ˵ÊÇÒѾ
¹ýʱÁË.Ò»µ©Äã³Ô±¥³ÅÖøÃ»Ê¸ÉҪȥ¿´¿´ËüµÄ»°,Ëü¾Í»á¸æËßÄãÕâ¼þÊÂ,½ÐÄã±ðÎÞÁ
ÄÁË.
4.2.1. ÆìÕýƮƮ~(flags)
ÔÚÃüÁîÁÐ(command
line)ÉÏÖ´ÐÐgccʱ,Ö»ÒªÔÚËüµÄƨ¹ÉááÃæ¼ÓÉÏ-OnµÄÑ¡Ïî,¾ÍÄÜÈÃgcc¹Ô¹ÔµÄÌæÄãÉú
³ö×î¼Ñ»¯ááµÄ»úÆ÷Âë(output
code).ÕâÀïµÄnÊÇÒ»¸ö¿ÉÓпÉÎÞµÄСÕûÊý.²»Í¬µÄgcc°æ±¾,nµÄÒâÒåÓëÆäÕýÈ·µÄ(ex
act)¹¦Ð§¶¼²»Ò»Ñù;²»¹ý,µäÐ͵ġõΧÊÇ´Ó0(²»Òª¼¦ÆÅ,ÎÒ²»Òª×î¼Ñ»¯)±ä»¯µ½2(×î
¼Ñ»¯Òª¶àÒ»µã),ÔÙµ½3(×î¼Ñ»¯ÒªÔÙ¶àÒ»µã,¶àÒ»µã).
gccÔÚÆäÄÚ²¿»á½«ÕâЩתÒë³ÉһϵÁеÄ-f
Óë-mÑ¡Ïî(options).Ö´ÐÐgccʱ´øÉÏÆìºÅ(flags)-vÓë-Q,Äã¾ÍÄܺÜÇå³þµÄ¿´³öÿÒ
»Öֵȼ¶µÄ-OÊǶÔÓ¦(maps)µ½ÄÇЩѡÏî(options).ÀýÈç,¾Í-O2À´½²,ÎÒµÄgcc¸æËßÎ
Ò˵:
enabled: -fdefer-pop -fcse-follow-jumps -fcse-skip-blocks
-fexpensive-optimizations
-fthread-jumps -fpeephole -fforce-mem -ffunction-cse -finline
-fcaller-saves -fpcc-struct-return -frerun-cse-after-loop
-fcommon -fgnu-linker -m80387 -mhard-float -mno-soft-float
-mno-386 -m486 -mieee-fp -mfp-ret-in-387
ÒªÊÇÄãÓõÄ×î¼Ñ»¯µÈ¼¶(optimization level)¸ßì¶ÄãµÄ±àÒëÆ÷ËùÄÜÖ§Ô®µÄ(e.g.
-O6),ÄÇ÷áËüµÄЧ¹û,¾Í¸úÄãÓÃÄãµÄ±àÒëÆ÷ËùÄÜÌṩµÄ×î¸ßµÈ¼¶µÄ,ÊÇÒ»ÑùµÄ½á¹û.
˵ʵÔÚµÄ,·¢ÐгöÈ¥µÄgcc³ÌʽÂë,ÓÃÔÚ±àÒëʱ¾¹ÊÇÈç´Ë´¦ÀíÕâµÈÎÊÌâ,ʵ·Çʲ÷áºÃ
µÄ¹¹Ïë.ÈÕááÈôÊÇÓиü½ø²½µÄ×î¼Ñ»¯·½·¨¾ßÌåÕûºÏµ½Ðµİ汾Àï,¶øÄã(»òÄãµÄuse
rs)»¹ÊÇÊÔÖøÕâÑù×öµÄ»°,¿ÉÄܾͻᷢÏÖ,gcc»áÖжÏÄãµÄ³Ìʽ(break your
code)ÁË.
´Ógcc
2.7.0µ½2.7.2µÄusersÓ¦¸Ã×¢Òâµ½,ʹÓÃʱ-O2»áÓÐÒ»¸öbug´æÔÚ.¸üÔã¸âµÄÊÇ,Ç¿¶È
ÕÛ¼õ(strength reduction)¾ÓȻûÓÐÓÃ(doesn't
work)!ÒªÊÇÄãϲ»¶ÖØÐ±àÒëgccµÄ»°,ÊÇÓÐÄÇ÷áÒ»¸öÐÞÕýµÄ°æ±¾(patch)¿ÉÒÔ¸üÕýÕ
âÏî´íÎó;²»È»µÄ»°,Ò»¶¨ÒªÈ·¶¨Ã¿´Î±àÒëʱ¶¼»á¼ÓÉÏ-fno-strength-reduceà¸!
11/12/97Òë
4.2.1.1. ÓиöÐÔµÄ΢´¦ÀíÆ÷(Processor-specific)
ÓÐһЩ-mµÄÆìºÅÎÞ·¨½åÓɸ÷Öֵȼ¶µÄ-OÀ´´ò¿ª,È»¶øÈ´ÊÇÊ®·ÖÓÐÓõÄ.ÕâÖ®ÖÐ×îÖ÷
ÒªµÄÊÇ-m386Óë-m486Á½ÖÖ,ÓÃÀ´¸æËßgcc¸Ã°ÑÕýÔÚ±àÒëµÄ³ÌʽÂëÊÓ×÷רΪ386»òÊÇ4
86»úÆ÷ËùдµÄ.²»ÂÛÊÇÓÃÄÄÒ»ÖÖÀ´±àÒë³ÌʽÂë,¶¼¿ÉÒÔÔڱ˴˵ĻúÆ÷ÉÏÖ´ÐÐ,-m486
±àÒë³öÀ´µÄÂë»á±È½Ï´ó,¿ÉÊÇÄÃÀ´ÔÚ386µÄ»úÆ÷ÉÏÅÜÒ²²»»á±È½ÏÂý¾ÍÊÇÁË.
ĿǰÉÐÎÞ-mpentium»òÊÇ-m586µÄÆìºÅ.Linus½¨ÒéÎÒÃÇ,¿ÉÒÔÓÃ-m486
-malign-loops=2 -malign-jumps=2
-malign-functions=2,À´µÃµ½×î¼Ñ»¯µÄ486³ÌʽÂë(486 code
optimizations),¶øÕâÑù×öÕýºÃ¾Í¿ÉÒÔ±ÜÃâalignment(Pentium²¢²»ÐèÒª)Óйý´óµ
Ägaps·¢Éú. Michael Meissner˵:
ÎҵĵÚÁù¸Ð(hunch)¸æËßÎÒ,
-mno-strength-reduce(ºÙ!Îҿɲ»ÊÇÔÚ̸ǿ¶ÈÕÛ¼õµÄbug°¡,ÄÇÒѾ
ÊÇÁíÍâÒ»¸öÕùÂÛµÄÕ½³¡ÁË.)Ò»ÑùÒ²¿ÉÒÔÔÚx86µÄ»úÆ÷ÉÏ,²úÉú½Ï¿ìµÄ³ÌʽÂë,Õâ
ÊÇÒòΪx86µÄ»úÆ÷¶ÔÔÝ´æÆ÷(register)ÓÐÖø²»¿ÉÄ¥ÃðµÄ¡õ¿ÊÔÚ(and GCC's
method of grouping registers into spill registers vs. other
registers doesn't hλ°ÈÔÊÇÀ´×Ôì¶Linus:
ҪעÒâµÄÊÇ,Èç¹ûÄãÏëÒªµÃµ½×î¼Ñ×´¿öµÄÖ´Ðгɹû(optimal
performance),¿ÉǧÍò±ðÏàÐÅÎҵϰ.ÎÞÂÛÈçºÎ,Ò»¶¨Òª½øÐвâÊÔ.gcc±àÒëÆ÷»¹
ÓÐÐí¶àµÄ²ÎÊý(switches)¿ÉÓÃ,ÆäÖпÉÄܾÍÓÐÒ»ÖÖ×îÌØ±ðµÄ×éºÏ(set),¿ÉÒÔ¸ø
Äã×î¼Ñ»¯µÄ½á¹ûà¸.
11/14/97Òë
4.2.2. Internal compiler error: cc1 got fatal signal 11
Signal 11ÊÇÖ¸ SIGSEGV, »òÕß `segmentation violation'.ͨ³£ÕâÊÇÖ¸
˵gcc¶Ô×Ô¼ºËùÓõÄÖ¸±ê¸Ðµ½À§»óÆðÀ´,¶øÇÒ»¹³¢ÊÔÖøÐ´Èë²»Êôì¶ËüµÄ¼ÇÒäÌå.ËùÒ
Ô,Õâ¿ÉÄÜÊÇÒ»¸ögccµÄbug.
È»¶ø,´ó²¿·Ý¶øÑÔ,gccÊÇÒ»¼þ¾
¹ýÑÏÃܲâÊÔÇÒ¿É¿¿¶È¼ÑµÄÈíÌå¼Ñ×÷.ËüÒ²ÓÃÁË´óÁ¿¸´ÔÓµÄ×ÊÁϽṹÓ뾪È˵ÄÖ¸±êÊ
ýÁ¿.¼òÑÔÖ®,ÈôÊÇÒªÆÀÑ¡±¾ÊÀ¼Í×îÌôÌèÓë×îһ˿²»¡õµÄRAM²âÊÔ³Ìʽ(RAM
tester)µÄ»°,gcc¾ø¶Ô¿ÉÒÔÒ»Õªºó¹ÚµÄ.¼ÙÈçÄãÎÞ·¨ÖØÐ¸´ÖÆÕâÖ»bug---µ±ÄãÖØÐÂ
¿ªÊ¼±àÒëʱ,´íÎóµÄѶϢ²¢Ã»ÓÐÒ»Ö±³öÏÖÔÚͬһ¸öµØ·½---ÄǼ¸ºõ¿ÉÒÔÈ·¶¨,ÊÇÄãµ
ÄÓ²Ìå±¾ÉíÓÐÎÊÌâ(CPU,¼ÇÒäÌå,Ö÷»ú°å»òÊÇ¿ìÈ¡¼ÇÒäÌå).ǧÍò²»ÒªÒòΪÄãµÄµçÄÔ¿
ÉÒÔͨ¹ý¿ª»ú³ÌÐòµÄ²âÊÔ(power-on
checks),»òÕßWindows¿ÉÒÔÅܵúÜ˳,»òÕ߯äËüʲ÷áµÄ,¾Í»Ø¹ýÍ·À´´óËÁÐû´«ËµÕâÊ
ÇgccµÄÒ»¸öbug;ÄãËù×öµÄÕâЩ²âÊÔ¶¯×÷,ͨ³£Ã»ÓÐʲ÷áʵ¼ÊÉϵļÛÖµ,¶øÇÒûÓмÛ
ÖµÒ²ÊǺܺÏÀíµÄ½áÂÛ.ÁíÍâ,Ò²²»ÒªÒòΪ±àÒëºËÐÄʱ,×ÜÊÇÍ£ÁôÔÚ`make
zImage'µÄ½×¶Î,¾ÍÒª´óÂîÕâÊÇgccµÄbug---µ±È»Ëü»áÍ£ÔÚÄǶù°¡!×ö`make
zImage'ʱ,ÐèÒª±àÒëµÄµµ°¸¿ÉÄܳ¬¹ý200µµ°¸;ÎÒÃÇÕýÔÚÑÐÄâÒ»¸ö±È½ÏСµÄµØ·½À´
È¡´ú.
Èç¹ûÄã¿ÉÒÔÖØ¸²²úÉúÕâ¸öbug,¶øÇÒ(×îºÃÊÇÕâÑùÀ²)¿ÉÒÔдһ¸ö¶ÌСµÄ³ÌʽÀ´Õ¹Ê¾
ÕâÖ»bugµÄ»°,Äã¾Í¿ÉÒÔ°ÑËü×ö³Ébug±¨±í(bug
report),È»ááemail¸øFSF,»òÕßÊÇlinux-gccÓʼþ±íÁÐ(linux-gcc mailing
list).Äã¿ÉÒÔÈ¥²Î¿¼gccµÄ˵Ã÷Îļþ,¿´¿´ÓÐʲ÷áÏêϸµÄ×ÊѶ,ÊÇËûÃÇËùÐèÒªµÄ.
4.3. ÒÆÖ²ÄÜÁ¦(Portability)
¾Ý±¨,½üÈÕÀ´Ðí¶àÕýÃæÏûÏ¢Ö¸³ö,ÈôÓÐij¼þ¶«¶«µ½ÏÖÔÚ¶¼»¹Ã»ÒÆÖ²µ½LinuxÉÏÈ¥,ÄÇ
÷á¿ÉÒԿ϶¨µÄÊÇ,ËüÒ»¶¨Ò»µã¼ÛֵҲûÓÐ.:-)
àÅ!Õý¾Ò»µã.Ò»°ã¶øÑÔ,ÔʼÂëÖ»ÐèÒª×öһЩ¾Ö²¿µÄÐÞ¸Ä(minor
changes),¾Í¿ÉÒÔ¿Ë·þ(get over)Linux
100%ÓëPOSIXÏàÈݵÄÌØÖÊ(compliance).Èç¹ûÄã×öÁËÈκεÄÐÞ¸Ä,¶ø½«´Ë²¿·Ý´«»Ø(
passing back)¸øÔ
×÷Õß,»áÊǺÜÓн¨ÉèÐԵľٶ¯(worthwhile).ÕâÑùÈÕáá¾ÍÖ»ÐèÒªÓõ½'make',¾ÍÄܵ
õ½Ò»¸ö¿ÉÖ´Ðеĵµ°¸ÁË.
4.3.1. BSD½ÌÅÉ£¨BSDisms£© (ÓÐ bsd_ioctl, daemon Óë <sgtty.h>)
±àÒë³Ìʽʱ,¿ÉÒÔÅäºÏ-I/usr/include/bsdÓëÁ¬½á-lbsdµÄ³Ìʽ¿â.(ÀýÈç:ÔÚÄãµÄM
akefileµµÄÚ,°Ñ-I/usr/include/bsd¼Óµ½CFLAGSÄÇÒ»ÐÐ;°Ñ-lbsd¼Óµ½LDFLAGSÄÇÒ
»ÐÐ).Èç¹ûÄãÕæµÄÄÇ÷áÏëÒªBSDÐÍ̬µÄÐźÅÐÐΪ(BSD type signal
behavior),Ò²²»ÔÙÐèÒª¼ÓÉÏ-D__USE_BSD_SIGNALÁË.ÄÇÊÇÒòΪµ±ÄãÓÃÁË-I/usr/in
clude/bsdÓ뺬À¨Á˱êÍ·µµ<signal.h>Ö®áá,make¾Í×Ô¶¯»á°ÑËü¼ÓÈëÁË.
4.3.2. ʧÂäµÄ·âÓ¡£¨`Missing' signals£©(SIGBUS, SIGEMT, SIGIOT, SIGTRAP,
SIGSYS etc)
LinuxÓëPOSIXÊÇÍêÈ«ÏàÈݵÄ.²»¹ý,ÓÐЩÐźŲ¢²»ÊÇPOSIX¶¨ÒåµÄ---ISO/IEC
9945-1:1990 (IEEE Std 1003.1-1990), paragraph B.3.3.1.1 sez:
"ÔÚPOSIX.1ÖÐÊ¡ÂÔÁËSIGBUS, SIGEMT, SIGIOT, SIGTRAP,
ÓëSIGSYSÐźÅ,ÄÇÊÇÒòΪËüÃǵÄÐÐΪ(behavior)Óëʵ×÷·½Ê½ÊÇϢϢÏà¹ØµÄ(imp
lementations dependent),¶øÇÒÒ²ÎÞ·¨½øÐÐÊʵ±µÄ·ÖÃűðÀà(adequately
categorized).È·ÈÏʵ×÷·½Ê½áá(conforming
implementations),±ã¿ÉÒÔÉú²ú³ö(deliver)ÕâЩÐźÅ,¿ÉÒÔ±ØÐëÒÔÎļþ˵Ã÷(d
ocument)ËüÃÇÊÇÔÚʲ÷áÑùµÄ»·¾³(circumstances)ÏÂÉú²ú³öÀ´µÄ,ÒÔ¼°Ö¸³öÓëË
üÃǵķ¢Õ¹Ïà¹ØµÄÈκÎÏÞÖÆ(any restrictions concerning their
delivery)".
ÈçÓûÐÞÕý´Ëµã,×î¼òµ¥,Ò²ÊÇ×µÄ(cheesy)·½·¨¾ÍÊÇÒÔSIGUNUSEDÖØÐ¶¨ÒåÕâЩÐ
źÅ.¶øÕýÈ·µÄ·½·¨Ó¦ÊÇÒÔÌõ¼þʽµÄ±àÒë#ifdefÀ´´¦ÀíÕâЩÎÊÌâ²Å¶Ô:
#ifdef SIGSYS
/* ... non-posix SIGSYS code here .... */
#endif
11/15/97Òë
4.3.3. K & R
gccÊǸöÓëANSIÏàÈݵıàÒëÆ÷;Ææ¹ÖµÄÊÇ,Ŀǰ´ó¶àÊýµÄ³ÌʽÂë¶¼²»·ûºÏANSIËù¶¨µ
ıê×¼.Èç¹ûÄãÈȰ®ANSI,ϲ»¶ÓÃANSIÌṩµÄ±ê×¼À´×«Ð´C³Ìʽ,ËÆºõ³ýÁËÔÚ±àÒëÆ÷µ
ÄÆìºÅÉϼÓÉÏ-traditionalÖ®Íâ,¾ÍûÓÐʲ÷áÆäËüµÄ¿ÉÒÔ¶à̸µÄÁË.There is a
certain amount of finer-grained control over which varieties of brain
damage to emulate;Çë×ÔÐвéÔÄgcc info page.
ҪעÒâµÄÊÇ,¾¡¹ÜÄãÓÃÁË-traditionalÀ´¸Ä±äÓïÑÔ,ËüµÄЧ¹ûÒ²½ö¾ÖÏÞÔÚgccËùÄܹ
»½ÓÊܵġõΧ.ÀýÈç, -traditional»á´ò¿ª(turn
on)-fwritable-strings,ʹµÃ×Ö´®³£Êý(string
constants)ÒÆÖÁ×ÊÁϼÇÒäÌå¿Õ¼ä(data space)ÄÚ(´Ó³ÌʽÂë¼ÇÒäÌå¿Õ¼ä(text
space),ÕâµØ·½ÊDz»ÄÜÈÎÒâдÈëµÄ).ÕâÑù×ö»áÈóÌʽÂëµÄ¼ÇÒäÌå¿Õ¼äÎÞÐÎÖÐÔö¼Óµ
Ä.
4.3.4. ǰÖô¦ÀíÆ÷(Preprocessor)µÄ·ûºÅîÉϺ¯ÊýÔÐÍÐû¸æ(prototypes)
×î³£¼ûµÄÎÊÌâÊÇ,ÈçÖÚËù½ÔÖª,LinuxÖÐÓÐÐí¶à³£Óõĺ¯Êý¶¼¶¨Òå³É¾Þ¼¯(macros)´
æ·ÅÔÚ±êÍ·µµ(header files)ÄÚ,´ËʱÈôÓÐÏàËÆµÄº¯ÊýÔ
ÐÍÐû¸æ³öÏÖÔÚ³ÌʽÂëÄÚ,ǰÖô¦ÀíÆ÷»á¾Ü¾ø½øÐÐÓï·¨·ÖÎö(parse)µÄǰÖÃ×÷Òµ.³£¼
ûµÄÓÐatoi()Óëatol().
4.3.5. sprintf()
Ôڴ󲿷ݵÄUnixϵͳÉÏ, sprintf(string, fmt,
...)´«»ØµÄÊÇstringµÄÖ¸±ê,È»¶ø,Õâ·½ÃæLinux(×ñÑ
ANSI)´«»ØµÄÈ´ÊÇ·ÅÈëstringÄÚµÄ×ÖÔªÊýÄ¿.½øÐÐÒÆÖ²Ê±,ÓÈÆäÊÇÕë¶ÔSunOS,ÐèÓо
¯¾õµÄÐÄ.
4.3.6. fcntl ÓëÏà¹ØµÄº¯Êý; FD_*¼Ò×åµÄ¶¨Òåµ½µ×°ÚÔÚÄÄÀï?
¾ÍÔÚ <sys/time.h>ÀïÍ·. ΪÁËÕæÕýµÄÔ
ÐÍÐû¸æ,µ±ÄãÓÃÁËfcntl,¿ÉÄÜÄãÒ²Ï뺬À¨±êÍ·µµ<unistd.h>½øÀ´.
Ò»°ã¶øÑÔ,º¯ÊýµÄmanual page»áÔÚSYNOPSISÕ½ÚÄÚÁгöÐèÒªµÄ±êÍ·µµ.
4.3.7. select()
µÄ¼ÆÊ±(time-out)---³ÌʽִÐÐʱ»á´¦ì¶Ã¦Âµ-µÈ´ýµÄ״̬(busy-waiting).
ºÜ¾ÃºÜ¾ÃÒÔǰ, select()µÄ¼ÆÊ±²ÎÊý(time-out
parameter)Ö»ÓжÁµÄÊôÐÔ(read-only)¶øÒÑ.¼´Ê¹µ½ÁË×î½ü,manual
pagesÈÔÈ»ÓÐÏÂÃæÕâ¶ÎµÄ¾¯¸æ:
select()ÕÕÀí½²Ó¦¸ÃÊǽåÓÉÊʵ±µÄÐÞÕýʱ¼äµÄÊýÖµ,ÔÙ´«»Ø×ÔÔ
ʼ¼ÆÊ±(original
time-out)¿ªÊ¼ááËùÊ£âŵÄʱ¼ä.δÀ´µÄ°æ±¾¿ÉÄÜ»áʹÕâÏÄÜʵÏÖ.Òò´Ë,¾ÍÄ
¿Ç°¶øÑÔ,Èô¼Ù¶¨ÔÚºô½Ðselect()Ö®áá,¼ÆÊ±Ö¸±ê(time-out
pointer)ÈÔÈ»²»»áÈÃÈ˸øÐÞÕý¹ý,¿ÉÊÇÒ»Öַdz£²»Ã÷ÖǵÄÏë·¨à¸!
δÀ´¾ÍÔÚÎÒÃǵÄÑÛǰÁË!ÖÁÉÙ,ÔÚÕâ¶ùÄã¾ø¶Ô¿ÉÒÔ¿´µ½.
º¯Êýselect()´«»ØµÄ,Êǿ۳ýµÈ´ýÉÐδµ½´ïµÄ×ÊÁÏËùºÄ·ÑµÄʱ¼äáá,ÆäÊ£âŵÄʱ¼ä
Öµ.Èç¹ûÔÚ¼ÆÊ±½áÊøÊ±,¶¼Ã»ÓÐ×ÊÁÏ´«ËͽøÀ´,¼ÆÊ±ÒýÊý(time-out
argument)±ã»áÉèΪ0;Èç¹û½ÓÖø»¹ÓÐÈκεÄselect(),ÒÔͬÑùµÄtime-out
structureÀ´ºô½Ð,ÄÇ÷áselect()±ã»áÁ¢¿Ì½áÊø.
ÈôÒªÐÞÕýÕâÏîÎÊÌâ,ֻҪÿ´Îºô½Ðselect()ǰ,¶¼°Ñ¼ÆÊ±ÊýÖµ(time-out
value)·Åµ½time-out structureÄÚ,¾ÍûÓÐÎÊÌâÁË.°ÑÏÂÃæµÄ³ÌʽÂë,
struct timeval timeout;
timeout.tv_sec = 1; timeout.tv_usec = 0;
while (some_condition)
select(n,readfds,writefds,exceptfds,&timeout);
¸Ä³É,
struct timeval timeout;
while (some_condition) {
timeout.tv_sec = 1; timeout.tv_usec = 0;
select(n,readfds,writefds,exceptfds,&timeout);
}
Õâ¸öÎÊÌâ,ÔÚÓÐЩ°æ±¾µÄMosaicÀïÊÇÏàµ±ÖøÃûµÄ,Ö»ÏûÒ»´ÎµÄµÈ´ý,Mosaic¾Í¹ÒÁË.
MosaicµÄÓ©Ä»ÓÒÉϽÇ,ÊDz»ÊÇÓиöÔ²Ô²µÄ,»áÐýתµÄµØÇò¶¯»
.ÄÇ¿ÅÇòתµÃÓú¿ì,¾Í±íʾ×ÊÁÏ´ÓÍøÂ·ÉÏ´«Ë͹ýÀ´µÄËÙÂÊÓúÂý!
4.3.8. ²úÉúÖжϵÄϵͳºô½Ð(Interrupted system calls)
4.3.8.1. áçÕ×(Symptom):
µ±Ò»Ö§³ÌʽÒÔCtrl-ZÖÐÖ¹(stop),È»ááÔÙÖØÐÂÖ´ÐÐ(restart)ʱ--»òÕßÊÇÆäËü¿ÉÒÔ
²úÉúCtrl-CÖжÏ(interruption)ÐźŵÄÇé¿ö,Èç×Ó³ÌÐò(child
process)ÖÕ½á(termination)µÈ--ϵͳ¾Í»á±§Ô¹Ëµ"interrupted system
call"»òÊÇ"write: unknown error",»òÕßÖîÈç´ËÀàµÄѶϢ.
4.3.8.2. ÎÊÌâµã:
POSIXµÄϵͳ¼ì²éÐźŵĴÎÊý,±ÈÆðһЩ¾É°æµÄUnixÊÇÒª¶àÄÇ÷áÒ»µã.Èç¹ûÊÇLinux
,¿ÉÄܾͻáÖ´ÐÐsignal handlersÁË--
* ·Çͬ²½µØ(asynchronously)(¼ÆÊ±Æ÷µÄµÎ´ðÉù)
* ϵͳºô½ÐµÄ´«»ØÖµ(on return from any system call)
* ÔÚÏÂÁÐϵͳºô½ÐµÄÖ´ÐÐÆÚ¼ä: select(), pause(), connect(),accept(),
read() on terminals, sockets, pipes or files in /proc, write() on
terminals, sockets, pipes or the line printer, open() on FIFOs,
PTYs or serial lines,ioctl() on terminals, fcntl() with command
F_SETLKW, wait4(), syslog(), any TCP or NFS operations.
¾ÍÆäËüµÄ×÷ҵϵͳ¶øÑÔ,ÄãÐèÒªµÄ¿ÉÄܾÍÊÇÏÂÃæÕâЩϵͳºô½Ð(system calls)ÁË:
creat(), close(), getmsg(), putmsg(), msgrcv(), msgsnd(), recv(),
send(), wait(), waitpid(), wait3(), tcdrain(), sigpause(), semop() to
this list.
ÔÚϵͳºô½ÐÆÚ¼ä,ÈôÓÐÒ»ÐźÅ(ÄÇÖ§³Ìʽ±¾ÉíӦ׼±¸ºÃhandlerÒòÓ¦ÁË)²úÉú,handl
er¾Í»á±»ºô½Ð.µ±handler½«¿ØÖÆÈ¨×ªÒÆ»ØÏµÍ³ºô½Ðʱ,Ëü»áÕì²â³öËüÒѾ
²úÉúÖжÏ,¶øÇÒ´«»ØÖµ»áÁ¢¿ÌÉ趨³É-1,errnoÉ趨³ÉEINTR.³Ìʽ²¢Ã»ÓÐÏëµ½»á·¢É
úÕâÖÖÊÂ,ËùÒԾͻábottles outÁË.
ÓÐÁ½ÖÖÐÞÕýµÄ·½·¨¿ÉÒÔÑ¡Ôñ:
(1) ¶Ôÿ¸öÄã×ÔÐа²×°(install)µÄsignal
handler,¶¼ÐëÔÚsigactionÆìºÅ¼ÓÉÏSA_RESTART.ÀýÈç,°ÑÏÂÁеijÌʽ,
signal (sig_nr, my_signal_handler);
¸Ä³É,
signal (sig_nr, my_signal_handler);
{ struct sigaction sa;
sigaction (sig_nr, (struct sigaction *)0, &sa);
#ifdef SA_RESTART
sa.sa_flags |= SA_RESTART;
#endif
#ifdef SA_INTERRUPT
sa.sa_flags &= ~ SA_INTERRUPT;
#endif
sigaction (sig_nr, &sa, (struct sigaction *)0);
}
ҪעÒâµÄÊÇ,µ±Õⲿ·ÝµÄ±ä¸ü´óÁ¿Ó¦Óõ½ÏµÍ³ºô½ÐÖ®áá,ºô½Ðread(),
write(),ioctl(), select(), pause() Óë
connect()ʱ,ÄãÈÔÈ»µÃ×ÔÐмì²é(check for)EINTR.ÈçÏÂËùʾ.
(2) Äã×Ô¼ºµÃºÜÃ÷È·µØ(explicitly)¼ì²éEINTR:
ÕâÀïÓÐÁ½¸öÕë¶Ôread()Óëioctl()µÄÀý×Ó.
ÔʼµÄ³ÌʽƬ¶Î,ʹÓÃread().
int result;
while (len > 0) {
result = read(fd,buffer,len);
if (result < 0) break;
buffer += result; len -= result;
}
Ð޸ijÉ,
int result;
while (len > 0) {
result = read(fd,buffer,len);
if (result < 0) { if (errno != EINTR) break; }
else { buffer += result; len -= result; }
}
ÔʼµÄ³ÌʽƬ¶Î,ʹÓÃioctl().
int result;
result = ioctl(fd,cmd,addr);
Ð޸ijÉ,
int result;
do { result = ioctl(fd,cmd,addr); }
while ((result == -1) && (errno == EINTR));
×¢ÒâÒ»µã,ÓÐЩ°æ±¾µÄBSD Unix,ÆäÄÚ¶¨µÄÐÐΪ(default
behaviour)ÊÇÖØÐÂÖ´ÐÐϵͳºô½Ð.ÈôÒªÈÃϵͳºô½ÐÖжÏ,µÃʹÓÃ
SV_INTERRUPT»òSA_INTERRUPTÆìºÅ.
4.3.9. ¿ÉÒÔдÈëµÄ×Ö´®(Writable strings)
gcc¶ÔÆäusers×Ü»³±§ÖøÀÖ¹ÛµÄÏë·¨(optimistic
view),ÏàÐŵ±ËûÃÇ´òËãÈÃij¸ö×Ö´®µ±×÷³£ÊýÀ´ÓÃʱ---ÄÇËü¾ÍÕæµÄÖ»ÊÇ×Ö´®³£Êý¶
øÒÑ.Òò´Ë,ÕâÖÖ×Ö´®³£Êý»á´¢´æÔÚ³ÌʽÂëµÄ¼ÇÒäÌåÇø¶ÎÄÚ(in the code area of
the
program).Õâ¿éÇøÓò¿ÉÒÔpageµ½´Åµú»úµÄimageÉÏ,±ÜÃâºÄµôswapµÄ¼ÇÒäÌå¿Õ¼ä,¶ø
ÇÒÈκγ¢ÊÔдÈëµÄ¾Ù¶¯¶¼»áÔì³É·ÖÒ³µÄ´íÎó(segmentation
fault).Õâ¿ÉÊÇÒ»ÖÖÌØÉ«ÄØ!
¶ÔÀϾÉÒ»µãµÄ³Ìʽ¶øÑÔ,
Õâ¿ÉÄÜ»á²úÉúÒ»¸öÎÊÌâ.ÀýÈç,ºô½Ðmktemp(),´«µÝÒýÊý(arguments)ÊÇ×Ö´®³£Êý.
mktemp()»á³¢ÊÔÖøÔÚ*Êʵ±µÄλÖÃ(in place)*ÖØÐÂдÈëËüµÄÒýÊý.
ÐÞÕýµÄ·½·¨²»Íâºõ(a)ÒÔ-fwritable-strings±àÒë,ÆÈʹgcc½«´Ë³£ÊýÖ÷ÅÔÚ×ÊÁϼ
ÇÒäÌå¿Õ¼ä(data space)ÄÚ.»òÕß(b)½«ÇÖ·¸µØÈ¨µÄ²¿·Ý(offending
parts)ÖØÐ¸Äд,ÅäÖÃÒ»¸ö²»Îª³£ÊýµÄ×Ö´®(non-constant
string),ÔÚºô½Ðǰ,ÏÈÒÔstrcpy()½«×ÊÁÏ¿½±´½øÈ¥.
4.3.10. Ϊʲ÷áºô½Ðexecl()»áʧ°Ü?
ÄÇÊÇÒòΪÄãºô½ÐµÄ·½Ê½²»¶Ô.execlµÄµÚÒ»¸öÒýÊýÊÇÄãÏëÒªÖ´ÐеijÌʽÃû.µÚ¶þ¸öÓ
ë½ÓÐøµÄÒýÊý»á±ä³ÉÄãËùºô½ÐµÄ³ÌʽµÄargvÕóÁÐ(array).¼Çס:´«Í³ÉÏ,argv[0]ÊÇ
Ö»Óе±³ÌʽûÓдøÖøÒýÊýÖ´ÐÐʱ,²Å»áÓÐÉ趨ֵ.ËùÒÔÂÞ,ÄãÓ¦¸ÃÕâÑùд:
execl("/bin/ls","ls",NULL);
¶ø²»ÊÇÖ»ÓÐ,
execl("/bin/ls", NULL);
Ö´ÐгÌʽ¶ø²»´øÈκÎÒýÊý(with no
arguments),¿É½âÊͳÉ(construe)ÊÇÒ»ÖÖÑûÇ뺯(invitation),Ä¿µÄÊǰѴ˳ÌʽµÄ
¶¯Ì¬³Ìʽ¿â¶ÀÁ¢(dynamic library dependencies)µÄÌØÐÔÓ¡³öÀ´(print
out).ÖÁÉÙ,a.outÊÇÕâÑùµÄ.¾ÍELF¶øÑÔ,ÊÂÇé¾Í²»ÊÇÕâÑùÁË.
(Èç¹ûÄãÏëµÃÖª´Ë³Ìʽ¿âµÄ×ÊѶ,ÓÐһЩ¸ü¼òµ¥µÄ½éÃæ¿ÉÓÃ;²Î¿¼¶¯Ì¬ÔØÈë(dynami
c loading)ÄÇÒ»Õ½Ú,»òÊÇlddµÄmanual page.)
11/16/97Òë
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
Previous: GCCµÄ°²×°(installation)ÓëÆôÓÃ(setup)
Next: Debugging and Profiling The Linux GCC HOWTOÖÐÒë°æV0.1 :
Debugging and Profiling
Previous: ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
Next: Á¬½á(Linking)
_________________________________________________________________
5. Debugging and Profiling
5.1. Preventative maintenance (lint)
lint¶ÔLinux¶øÑÔ²¢Ã»Óкܹ㷺µÄÓÃ;,Ö÷ÒªÊÇÒòΪ´ó²¿·ÝµÄÈ˶¼ÄÜÂú×ãì¶gccËùÌ
ṩµÄ¾¯¸æÑ¶Ï¢(warnings).¿ÉÄÜ×îÓÐÓõľÍÊÇ-Wall²ÎÊýÁË---Õâ¸ö²ÎÊýµÄÓÃ;ÊÇ
ÒªÇógcc½«ËùÓеľ¯¸æÑ¶Ï¢ÏÔÏÖ³öÀ´.but probably has more mnemonic value
if thought of as the thing you bang your head against.
ÍøÂ·ÉÏÓÐÒ»¸öʵÓõÄpublic domain lint,λì¶
ftp://larch.lcs.mit.edu/pub/Larch/lclint.ÎÒ²¢²»ÖªµÀÕâ¸öÕ¾µ½µ×ÓжàºÃ¾ÍÊ
ÇÁË.
5.2. ³ý´í(Debugging)
5.2.1. ÎÒÒªÔõÑù×ö²ÅÄܽ«³ý´í×ÊѶ·Åµ½Ò»Ö§³ÌʽÀïÍ·?
ÄãÐèÒªÌí¼Ó-gµÄ²ÎÊýÀ´±àÒëÓëÁ¬½á³Ìʽ,¶øÇÒ²»¿ÉÒÔÓÃ-fomit-frame-pointer²ÎÊ
ý.ÊÂʵÉÏ,Äã²»ÐèÒªÖØÐ±àÒëËùÓеijÌʽ,Ö»ÐèÖØÐ±àÒëĿǰÄãÕýÔÚ³ý´íµÄ²¿·Ý¼´
¿É.
¾Ía.outµÄ¸ñʽ(configurations)¶øÑÔ,¹²Ïí³Ìʽ¿â(shared
libraries)ÊÇÒÔ-fomit-frame-pointer±àÒë¶ø³É,Õâ¸öʱºò,gdb¾Í±äµÃÓ¢ÐÛÎÞÓÃÎ
äÖ®µØÁË.Á¬½áʱ¸ø¶¨-gµÄÑ¡Ïî,Ó¦¸Ã¾ÍÒþº¬Öø¾²Ì¬Á¬½á(static
linking)ÁË;Õâ¾ÍÊÇΪʲ÷áÒª¼Ó-gµÄÔÒòÁË.
Èç¹ûÁ¬½áÆ÷(linker)Á¬½áʧ°Ü,¸æËßÄãÕÒ²»µ½libg.a,ÄǾÍÊÇÔÚ/usr/lib/µÄĿ¼µ
×ÏÂ,ÉÙÁËlibg.a.libg.aÊÇÌØÊâµÄCÓïÑÔÕì´í³Ìʽ¿â(special debugging-enabled
C
library).Ò»°ãÔÚlibcµÄÌ×¼þÄھͻáÌṩlibg.a;²»È»µÄ»°(аæÊÇÕâÑùµÄ),Äã¿ÉÄ
ÜÐèÒªÄÃlibcµÄÔ
ʼÂë×Ô¼º½¨Á¢ÁË.²»¹ý,ʵ¼ÊÉÏÄãÓ¦¸Ã²»ÐèÒª²Å¶Ô.²»¹ÜÊÇʲ÷áÄ¿µÄ,´ó²¿·ÝµÄÇé¿ö
ÏÂ,Ö»Ð轫libg.aÁ¬½áµ½/usr/lib/libc.a,Äã¾ÍÄܵõ½×ã¹»µÄ×ÊѶÁË.
5.2.1.1. ÄÇ,Äܲ»Äܰѳý´í×ÊѶ¸øÄõô?
ºÜ¶àµÄGNUÈíÌåÔÚ±àÒëÁ¬½áʱ,¶¼»áÉ趨-gµÄÑ¡Ïî,¶øÕâÑù×ö»áÔì³ÉÖ´Ðеµ¹ý´óµÄÎ
ÊÌâ(ͨ³£ÊǾ²Ì¬µÄ).ʵ¼ÊÉÏ,Õâ²¢²»ÊÇÒ»¸öºÜÈÈÃŵÄÏë·¨.
Èç¹û³Ìʽ±¾ÉíÓÐautoconf,²úÉúÁËconfigureÃüÁî¸å,ͨ³£Äã¾Í¿ÉÒÔÓÃ./configure
CFLAGS=»òÊÇ./configure
CFLAGS=-O2À´¹Øµô³ý´í×ÊѶ.²»È»µÄ»°,ÄãµÃ¼ì²é¼ì²éMakefileÁË.µ±È»À²,¼ÙÈçÄã
ÓõÄÊÇELF,³Ìʽ±ã»áÒÔ¶¯Ì¬µÄ·½Ê½Á¬½á(dynamically
linked),²»ÂÛÊÇ·ñÓÐ-gµÄÉ趨;Òò´ËÄã¿ÉÒÔÆ½³£ÐİÑ-gÄõô(strip).
5.2.2. ʵÓõÄÈíÌå(Available software)
¾ÝÁ˽â,Ò»°ãÈ˶¼Ê¹ÓÃgdb.Äã¿ÉÒÔ´ÓGNU archive sitesÄõ½Ô
ʼ³Ìʽ;»òÕßÊǵ½tsx-11ÄÿÉÖ´Ðеµ.xxgdbÊÇÒ»¸öX½éÃæµÄ³ý´í³Ìʽ(debugger),Ö
²»ùì¶gdb(Ò²¾ÍÊÇ˵ÄãµÃÏȰ²×°ºÃgdb,²ÅÄÜÔÙ×°xxgdb).xxgdbµÄÔ
ʼÂë¿ÉÒÔÔÚftp://ftp.x.org/contrib/xxgdb-1.08.tar.gzÕÒµ½.
ÁíÍâ,UPS³ý´í³ÌʽÒÑÓÉRick
SladkeyÒÆÖ²³É¹¦.UPS¿ÉÒÔÔÚXµ×Ï»îµÃºÜºÃ,²»ÏñxxgdbÄÇÑù---½ö½öÊÇgdbµÄXǰ¶
˽éÃæ(X front end).ÕâÖ§³ý´í³ÌʽÓÐÒ»´ó¶ÑÓÅÁ¼µÄÌØµã,and if you spend any
time debugging stuff, you probably should check it
out.ÏÈǰ±àÒë(precompiled)ºÃµÄLinux°æÓëÐÞÕý°æ(patches)µÄÔ
ʼÂë¿ÉÒÔÔÚftp://sunsite.unc.edu/pub/Linux/devel/debuggers/ÕÒµ½.¶ø×î³õµ
ÄÔʼ³ÌʽÔò·ÅÔÚ ftp://ftp.x.org/contrib/ups-2.45.2.tar.Z.
Äã¿ÉÄܻᷢÏÖÁíÒ»¸öÓÃÀ´³ý´íµÄ¹¤¾ßstrace,Ò²ÊÇÏ൱µÄÓÐÓÃ.Ëü¿ÉÒÔÏÔʾ³öÓɳÌ
Ðò(process)Ëù²úÉúµÄϵͳºô½Ð,¶øÇÒ»¹ÓµÓÐÆäËüÖÚ¶à·±¸´µÄ¹¦ÄÜ(multiplicity)
,ÏñÊÇÈç¹ûÄãÊÖ±ßûÓÐÔʼÂëµÄ»°,strace¿ÉÒÔ°ïÄãÕÒ³ö(figure
out)ÓÐÄÇЩ·¾¶(path-names)ÒѱàÒë½øÖ´Ðеµ(binaries)ÄÚ; exacerbating
race conditions in programs that you suspect contain
them;»¹ÓÐ,strace¿ÉÄÃÀ´Ñ§Ï°³ÌʽÊÇÔõ÷áÔÚµçÄÔÖÐÖ´ÐеÄ.×îеİ汾(ĿǰÊÇ3.
0.8)¿ÉÔÚÕÒµ½ftp://ftp.std.com/pub/jrs/.
5.2.3. ±³¾°³Ìʽ(Background (daemon) programs)
ÔçÆÚµäÐ͵ij£×¤³Ìʽ(daemon
programs)ÊÇÖ´ÐÐfork(),È»ááÖÕÖ¹(terminate)¸¸³ÌÐò(parent).ÕâÑùµÄ×ö·¨Ê¹µÃ
³ý´íµÄʱ¼ä¼õ¶ÌÁË.
Á˽â(get
around)ÕâµãµÄ×î¼òµ¥µÄ·½·¨¾ÍÊÇÌæfork()ÉèÒ»¸öbreakpoint.µ±³Ìʽֹͣʱ,Ç¿Æ
Èfork()´«»Ø0.
(gdb) list
1 #include <stdio.h>
2
3 main()
4 {
5 if(fork()==0) printf("child\n");
6 else printf("parent\n");
7 }
(gdb) break fork
Breakpoint 1 at 0x80003b8
(gdb) run
Starting program: /home/dan/src/hello/./fork
Breakpoint 1 at 0x400177c4
Breakpoint 1, 0x400177c4 in fork ()
(gdb) return 0
Make selected stack frame return now? (y or n) y
#0 0x80004a8 in main ()
at fork.c:5
5 if(fork()==0) printf("child\n");
(gdb) next
Single stepping until exit from function fork,
which has no line number information.
child
7 }
5.2.4. ºËÐĵµ°¸(Core files)
µ±Linux¿ª»úʱ,ͨ³£×é̬(configuration)»áÉ趨³É²»Òª²úÉúºËÐĵµ°¸.ÒªÊÇÄãÄÇ
÷áϲ»¶ËüÃǵϰ,¿ÉÒÔÓÃshellµÄbuiltinÃüÁîʹÆäÖØÐÂÉúЧ:¾ÍC-shellÏàÈݵÄshe
ll(Èçtcsh)¶øÑÔ,»áÊÇÏÂÃæÕâÑù:
% limit core unlimited
¶øÀàËÆBourne shellµÄshell(sh,bash,zsh,pdksh)ÔòʹÓÃÏÂÃæµÄÓï·¨:
$ ulimit -c unlimited
Èç¹ûÄãÏëÒªÓиö¶à²Å¶àÒÕ(versatility)µÄºËÐĵµÃüÃû(core file naming)(for
example, if you're trying to conduct a post-mortem using a debugger
that's buggy itself)
,ÄÇ÷áÄã¿ÉÒÔ¶ÔÄãµÄºËÐijÌʽ(kernel)×öÒ»µãССµÄ¸ü¶¯(mod).ÕÒÒ»ÕÒfs/binfmt
_aout.cÓëfs/binfmt_elf.cµµÄÚÓëÏÂÁÐÏà·ûµÄ³ÌʽƬ¶Î(in newer kernels,
you'll have to grep around a little in older ones):
memcpy(corefile,"core.",5);
#if 0
memcpy(corefile+5,current->comm,sizeof(current->comm));
#else
corefile[4] = '\0';
#endif
½«0»»³É1.
5.3. ÅÔÇòà»÷(Profiling)
ProfilingÊÇÓÃÀ´¼ìºËÒ»Ö§³ÌʽÖÐÄÇЩ²¿·Ý(which
bits)ÊÇ×î³£ºô½Ð»òÊÇÖ´ÐеÄʱ¼ä×î¾ÃµÄ·½·¨.Õâ¶Ô³ÌʽµÄ×î¼Ñ»¯ÓëÕÒ³öºÎʱʱ¼ä
ÊÇÀ˷ѵôµÄ¶øÑÔ,ÊÇÏ൱ºÃµÄ·½Ê½.Äã±ØÐë¾ÍÄãËùÒªµÄʱ³Ì×ÊѶ(timing
information)µÄÄ¿µÄµµ°¸(object
files)¼ÓÉÏ-pÀ´±àÒë,¶øÇÒÈç¹ûÒªÈÃÊä³öµÄµµ°¸(output files)ÓÐÒâÒå(make
sense),ÄãÒ²»áÐèÒªgprof(À´×ÔbinutilsÌ×¼þµÄÃüÁî).²ÎÔÄgprofµÄmanual
page,¿ÉµÃÖªÆäϸ½Ú.
11/18/97Òë
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : Debugging and Profiling
Previous: ÒÆÖ²(Porting)Óë±àÒë(Compiling)³Ìʽ
Next: Á¬½á(Linking) The Linux GCC HOWTOÖÐÒë°æV0.1 : Á¬½á(Linking)
Previous: Debugging and Profiling
Next: ¶¯Ì¬ÔØÈë(Dynamic Loading)
_________________________________________________________________
6. Á¬½á(Linking)
ÓÉì¶¾²Ì¬(static)Óë¹²Ïí(shared)³Ìʽ¿âÁ½Õ߼䲻ÏàÈݵĸñʽ(incompatible
binary
formats)µÄ²îÒìÐÔ(distinction)Ó붯´Ê*link*¹ýÁ¿Ê¹ÓÃ(overloading)ì¶Ö¸³Æ*±
àÒëÍê³ÉááµÄÊÂÇé*Óë*µ±±àÒë¹ýµÄ³ÌʽʹÓÃʱ(invoke)Ëù·¢ÉúµÄÊÂÇé*ÕâÁ½¼þÊÂÉÏ
Í·,ʹµÃÕâÒ»Õ½ڱäµÃ¸´ÔÓÁËÐí¶à.( and, actually, the overloading of the
word `load' in a comparable but opposite
sense)²»¹ý,ÔÙ¸´ÔÓÒ²¾ÍÊÇÕâÑùÁË,ËùÒÔ¸óϲ»±Ø¹ýì¶µ£ÐÄ.
ΪÁËÉÔ΢¼õÇá¶ÁÕßµÄÀ§»ó,ÎÒÃdzÆÖ´ÐÐÆÚ¼ä(runtime)Ëù·¢ÉúµÄÊÂΪ*¶¯Ì¬ÔØÈë(dy
namic
loading)*,ÕâÒ»Ö÷Ìâ»áÔÚÏÂÒ»Õ½ÚÖÐ̸µ½.ÄãÒ²»áÔÚ±ðµÄµØ·½¿´µ½ÎҰѶ¯Ì¬ÔØÈëÃ
èÊö³É*¶¯Ì¬Á¬½á(dynamic
linking)*,²»¹ý²»»áÊÇÔÚÕâÒ»Õ½ÚÖÐ.»»¾ä»°Ëµ,ÕâÒ»Õ½ÚËù̸µÄ,È«²¿ÊÇÖ¸·¢ÉúÔ
Ú±àÒë½áÊøááµÄÁ¬½á(linking).
6.1. ¹²Ïí³Ìʽ¿â vs¾²Ì¬³Ìʽ¿â
½¨Á¢³ÌʽµÄ×îááÒ»¸ö²½Öè±ãÊÇÁ¬½á;Ò²¾ÍÊǽ«ËùÓзÖÉ¢µÄС³Ìʽ(pieces)×éºÏÆðÀ
´,¿´¿´ÊÇ·ñÒÅ©ÁËЩʲ÷á.ºÜÃ÷ÏÔµÄ,ÓÐһЩÊÂÇéÊǺܶà³Ìʽ¶¼»áÏë×öµÄ---ÀýÈç,
¿ªÆôµµ°¸(open
files),½ÓÖøËùÓÐÓ뿪µµÓйصÄС³Ìʽ(pieces)¾Í»áÒÔ³Ìʽ¿âµÄµµ°¸ÐÍ̬Ìṩ¸øÄ
ãµÄ³Ìʽ.ÔÚÆÕͨµÄLinuxϵͳÉÏ,ÕâЩС³Ìʽ¿ÉÒÔÔÚ/libÓë/usr/lib/Ŀ¼µ×ÏÂÕÒµ
½.
µ±ÄãÓõÄÊÇÒ»¾²Ì¬µÄ³Ìʽ¿âʱ,Á¬½áÆ÷»áÕÒ³ö³ÌʽËùÐèµÄÄ£×é(bits),È»ááʵ¼Ê(p
hysically)½«ËüÃÇ¿½±´µ½Ö´ÐеµÄÚ.È»¶ø,¶Ô¹²Ïí³Ìʽ¿â¶øÑÔ,¾Í²»ÊÇÕâÑùÁË.¹²Ïí
³Ìʽ¿â»áÔÚÖ´ÐеµÄÚÁôÏÂÒ»¸ö·ûºÅ(note),Ö¸Ã÷*µ±³ÌʽִÐÐʱ,Ê×ÏȱØÐëÔØÈëÕâ¸
ö³Ìʽ¿â*.ºÜÃ÷ÏÔµÄ,¹²Ïí³Ìʽ¿âÊÇÊÔͼʹִÐеµ±äµÃ¸üС;Ò²µÈͬì¶Ê¹ÓøüÉٵļ
ÇÒäÌåÓë´Åµú¿Õ¼ä.LinuxÄÚ¶¨µÄÐÐΪÊÇÁ¬½á¹²Ïí³Ìʽ¿â,Ö»ÒªLinuxÄÜÕÒµ½ÕâЩ¹²Ï
í³Ìʽ¿âµÄ»°,¾Íûʲ÷áÎÊÌâ;²»È»,Linux¾Í»áÁ¬½á¾²Ì¬µÄÁË.Èç¹ûÄãÏëÒª¹²Ïí³Ìʽ
¿âµÄ»°,¼ì²éÕâЩ³Ìʽ¿â(*.sa for a.out, *.so for
ELF)ÊÇ·ñסÔÚËüÃǸÃÔڵĵط½,¶øÇÒÊǿɶÁÈ¡µÄ.
ÔÚLinuxÉÏ,¾²Ì¬³Ìʽ¿â»áÓÐÀàËÆlibname.aÕâÑùµÄÃû³Æ;¶ø¹²Ïí³Ìʽ¿âÔò³Æ×ölibn
ame.so.x.y.z,´Ë´¦µÄx.y.zÊÇÖ¸°æ±¾ÐòºÅµÄÑùʽ.¹²Ïí³Ìʽ¿âͨ³£¶¼»áÓÐÁ¬½á·ûº
ÅÖ¸Ïò¾²Ì¬³Ìʽ¿â(ºÜÖØÒªµÄ)Óë(on a.out
configurations)Ïà¹ØÁªµÄ.saµµ°¸.±ê×¼µÄ³Ìʽ¿â»á°üº¬¹²ÏíÓ뾲̬³Ìʽ¿âÁ½ÖÖ¸
ñʽ.
Äã¿ÉÒÔÓÃldd (List Dynamic
Dependencies)À´²é³öij֧³ÌʽÐèÒªÄÄЩ¹²Ïí³Ìʽ¿â.
$ ldd /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
ÕâÊÇ˵ÔÚÎÒµÄϵͳÉÏ,WWWä¯ÀÀÆ÷(browser)*lynx*»áÒÀÀµlibc.so.5 (the C
library)Óëlibncurses.so.1(ÖÕ¶Ë»úÓ©Ä»µÄ¿ØÖÆ)µÄ´æÔÚ(presence).Èôij֧³Ìʽ
ȱ·¦¶ÀÁ¢ÐÔ(dependencies), ldd¾Í»á˵`statically linked'»òÊÇ`statically
linked (ELF)'.
6.2. Interrogating libraries (`which library is sin() in?')
nm ³Ìʽ¿âÃû³Æ
Ó¦¸Ã»áÁгö´Ë³Ìʽ¿âÃû³ÆËù²Î¿¼µ½µÄËùÓзûºÅ(symbols).Õâ¸öÖ¸Áî¿ÉÒÔÓ¦ÓÃÔÚ¾²
̬Óë¹²Ïí³Ìʽ¿âÉÏ.¼ÙÉèÄãÏëÖªµÀtcgetattr()ÊÇÔÚÄĶù¶¨ÒåµÄ:Äã¿ÉÒÔÈç´Ë×ö
$ nm libncurses.so.1 |grep tcget
U tcgetattr
*U*˵Ã÷ÁË*䶨Òå(undefined)*---Ò²¾ÍÊÇ˵ncurses³Ìʽ¿âÓÐÓõ½tegetattr(),
µ«ÊDz¢Ã»Óж¨ÒåËü.ÄãÒ²¿ÉÒÔÕâÑù×ö,
$ nm libc.so.5 | grep tcget
00010fe8 T __tcgetattr
00010fe8 W tcgetattr
00068718 T tcgetpgrp
*W*˵Ã÷ÁË*ÈõÊÆ(weak)*,ÒâÖ¸·ûºÅËäÒѶ¨Òå,µ«¿ÉÓɲ»Í¬³Ìʽ¿âÖеÄÁíÒ»¶¨ÒåËùÈ
¡´ú(overridden).¶ø×îÖ±½ÓµÄ(straightforward)*Õý³£(normal)*¶¨Òå(ÏñÊÇtcge
tpgrp)ÊÇÓÉ*T*Ëù±êʾ.
±êÌâËù̸µÄÎÊÌâ,×î¼òÃ÷µÄ´ð°¸±ãÊÇlibm.(so|a)ÁË.ËùÓж¨ÒåÔÚ<math.h>µÄº¯Êý¶
¼±£ÁôÔÚmaths³Ìʽ¿âÄÚ;Òò´Ë,µ±ÄãÓõ½ÆäÖÐÈκÎÒ»¸öº¯Êýʱ,¶¼ÐèÒªÒÔ-lmµÄ²ÎÊý
Á¬½á´Ë³Ìʽ¿â.
6.3. Xµµ°¸???
ld: Output file requires shared library `libfoo.so.1`
ldÓëÆäÏàÀàËÆµÄÃüÁîÔÚËÑѰµµ°¸µÄ²ßÂÔ(strategy)ÉÏ,»áÒÀ¾Ý°æ±¾µÄ²îÒì¶øÓÐËù²
»Í¬,µ«ÊÇΨһһ¸öÄã¿ÉÒÔºÏÀí¼ÙÉèµÄÄÚ¶¨Ä¿Â¼±ãÊÇ/usr/libÁË.Èç¹ûÄãÏ£ÍûÉí´¦Ë
ü´¦µÄ³Ìʽ¿âÒ²ÁÐÈëËÑѰµÄÐÐÁÐÖÐ,ÄÇ÷áÄã¾Í±ØÐëÒÔ-LÑ¡Ïî¸æÖªgcc»òÊÇld.
ÒªÊÇÄã·¢ÏÖÒ»µãЧ¹ûҲûÓÐ,¾Í¸Ï½ô²ì¿´¿´Äǵµ°¸ÊDz»ÊÇ»¹¹Ô¹ÔµÄÌÉÔÚÔ
µØ.¾Ía.out¶øÑÔ,ÒÔ-lfoo²ÎÊýÀ´Á¬½á,»áÇýʹldȥѰÕÒlibfoo.sa (shared
stubs);Èç¹ûûÓгɹ¦,¾Í»á»»³ÉѰÕÒlibfoo.a (static).¾ÍELF¶øÑÔ,
ld»áÏÈÕÒlibfoo.so,È»ááÊÇlibfoo.a.libfoo.soͨ³£ÊÇÒ»¸ö·ûºÅÁ¬½á,Á¬½áÖÁlib
foo.so.x.
6.4. ½¨Á¢Äã×Ô¼ºµÄ³Ìʽ¿â(Building your own libraries)
6.4.1. °æ±¾¿ØÖÆ(Version control)
ÓëÆäËüÈκεijÌʽһÑù,³Ìʽ¿âÒ²ÓÐÐÞÕý²»ÍêµÄbugsµÄÎÊÌâ´æÔÚ.ËüÃÇÒ²¿ÉÄܲúÉú
³öһЩеÄÌØµã,¸ü¸ÄĿǰ´æÔÚµÄÄ£×éµÄ¹¦Ð§,»òÊǽ«¾ÉµÄÒÆ³ýµô.Õâ¶ÔÕýÔÚʹÓÃË
üÃǵijÌʽ¶øÑÔ,¿ÉÄÜ»áÊÇÒ»¸ö´óÎÊÌâ.Èç¹ûÓÐÒ»Ö§³ÌʽÊǸù¾ÝÄÇЩ¾ÉµÄÌØµãÀ´Ö´Ð
еϰ,ÄÇÔõ÷á°ì?
ËùÒÔ,ÎÒÃÇÒý½ø(introduce)Á˳Ìʽ¿â°æ±¾±àºÅ(versioning)µÄ¹ÛÄî.ÎÒÃǽ«³Ìʽ¿
â*´ÎÒª(minor)*Óë*Ö÷Òª(major)*µÄ±ä¸ü·ÖÃűðÀà(categorize),ͬʱÎÒÃǹ涨*´
ÎÒª*µÄ±ä¸üÊDz»ÔÊÐíÓõ½Õâ³Ìʽ¿âµÄ¾É³Ìʽ·¢ÉúÖжϵÄÏÖÏó(break).Äã¿ÉÒÔ´Ó³Ì
ʽ¿âµÄµµÃû·Ö±æ³öËüµÄ°æ±¾(ʵ¼ÊÉÏ,ÑϸñÀ´½²,¶ÔELF¶øÑÔ½ö½öÊÇÒ»³¡Ìì´óµÄ»ÑÑÔ
;¼ÌÐø¶Á½«ÏÂÈ¥,±ã¿ÉÃ÷°×Ϊʲ÷áÁË):
libfoo.so.1.2µÄÖ÷Òª°æ±¾ÊÇ1,´ÎÒª°æ±¾ÊÇ2.´ÎÒª°æ±¾µÄ±àºÅ¿ÉÄÜÕæÓÐÆäÊÂ,Ò²¿É
ÄÜʲ÷ᶼûÓÐ---libcÔÚÕâÒ»µãÉÏÓÃÁË*ÐÞÕý³Ì¶È(patch-level)*µÄ¹ÛÄî,¶ø¸ø³öÁ
ËÃû³ÆÏñlibc.so.5.2.18ÕâÑùµÄ³Ìʽ¿â.´ÎÒª°æ±¾µÄ±àºÅÄÚÈôÊÇ·ÅһЩ×Öĸ,µ×Ïß,
»òÊÇÈκοÉÒÔÁÐÓ¡µÄASCII×ÖÔª,Ò²ÊǺܺÏÀíµÄ˵.
ELFÓëa.out¸ñʽ×îÖ÷ÒªµÄ²î±ðÖ®Ò»¾ÍÊÇÔÚ½¨Á¢¹²Ïí³Ìʽ¿âÉÏ.ÎÒÃÇÏÈ¿´ELF,ÒòΪË
ü±È½Ï¼òµ¥Ò»Ð©.
6.4.2. ELF? Ëüµ½µ×ÊÇʲ÷á¶«¶«¨Ë¨ß?
ELF (Executable and Linking Format) ×î³õÊÇÓÉUSL(UNIX System
Laboratories)Ëù·¢Õ¹µÄ¶þ½øÎ»¸ñʽ(binary
format),¶øÄ¿Ç°ÕýÓ¦ÓÃì¶SolarisÓëSystem V Release
4ÉÏÃæ.ÓÉì¶ELFËùÔöÕǵĵ¯ÐÔ(flexibility)Ô¶Ô¶³¬¹ýLinux¹ýÈ¥ËùÓõÄa.out¸ñʽ
,Òò´ËGCCÓëC³Ìʽ¿âµÄ·¢Õ¹ÈËÊ¿ì¶È¥Äê(1995)¾ö¶¨¸ÄÓÃELFΪLinux±ê×¼µÄ¶þ½øÎ»¸
ñʽ.
6.4.2.1. Ôõ÷áÓÖÀ´ÁË?
ÕâÒ»½ÚÊÇÀ´×Ôì¶'/news-archives/comp.sys.sun.misc'µÄÎļþ.
ELF("Executable Linking
Format")ÊÇì¶SVR4ËùÒý½øµÄÐÂʽ¸ÄÁ¼Ä¿µÄµµ¸ñʽ.ELF±ÈÆðCOFF¿ÉÊǶà³öÁ˲»É
ٵŦÄÜ.ÒÔELF¶øÑÔ,Ëü*ÊÇ*¿ÉÓÉʹÓÃÕß×ÔÐÐÑÓÉìµÄ(user-extensible).ELFÊÓ
һĿµÄµµÎª½ÚÇø(sections)Èç´®ÁаãµÄ×éºÏ,¶øÇÒ´Ë´®ÁпÉΪÈÎÒâµÄ(arbitra
rily)³¤¶È(¶ø²»ÊÇÒ»¹Ì¶¨´óСµÄÕóÁÐ).ÕâЩ½ÚÇøÓëCOFFµÄ²»Ò»Ñù,²¢²»ÐèÒª¹Ì
¶¨ÔÚij¸öµØ·½,Ò²²»ÐèÒªÒÔijÖÖ˳ÐòÅÅÁÐ.Èç¹ûusersÏ£ÍûÄܲ¹×½µ½ÐµÄ×ÊÁÏ,Ë
ûÃDZã¿ÉÒÔ¼ÓÈëеĽÚÇøµ½Ä¿µÄµµÄÚ.ELFÒ²ÓÐÒ»¸ö¸üÇ¿¶øÓÐÁ¦µÄ³ý´í¸ñʽ,³ÆÎ
ªDWARF(Debugging With Attribute Record
Format)-ĿǰLinux²¢²»Íêȫ֧Ԯ.DWARF DIEs(Debugging Information
Entries)µÄÁ¬½á´®ÁлáÔÚELFÄÚÐγÉ.debugµÄ½ÚÇø.DWARF
DIEsµÄÿһ¸ö.debug½ÚÇø²¢·ÇһЩÉÙÁ¿µÄ(small)Çҹ̶¨´óСµÄ(fixed-size)
×ÊѶ¼Ç¼(information
records)µÄ¼¯ºÏ(collection),¶øÊÇÒ»ÈÎÒⳤ¶ÈµÄ´®ÁÐ,ÓµÓи´ÔÓµÄÊôÐÔ,¶øÇÒ
³ÌʽµÄ×ÊÁÏ»áÒÔ¡õΧΪ¸ù¾ÝµÄÊ÷×´×ÊÁϽṹ(scope-based
tree)д³öÀ´.DIEsËùÄܲ¹×½µ½µÄ´óÁ¿×ÊѶÊÇCOFFµÄ.debug½ÚÇøÎÞ·¨ÍûÆäÏî±³µ
Ä.(ÏñÊÇC++µÄ¼Ì³Ðͼ).
ELFµµ°¸ÊÇ´ÓSVR4(Solaris 2.0 ?)ELF´æÈ¡³Ìʽ¿â(ELF access
library)ÄÚ´æÈ¡µÄ.´Ë³Ìʽ¿â¿ÉÌṩһ¼ò±ã¿ìËٵĽéÃæÓèELF.ʹÓÃELF´æÈ¡³ÌÊ
½¿â×îÖ÷ÒªµÄ¶÷»ÝÖ®Ò»±ãÊÇ,Äã²»ÔÙÐèҪȥ²ì¿´Ò»¸öELFµµµÄquaÁË.¾ÍUNIXµÄµµ
°¸¶øÑÔ,ËüÊÇÒÔElf*µÄÐÍʽÀ´´æÈ¡;ºô½Ðelf_open()Ö®áá,´Ó´Ëʱ¿ªÊ¼,ÄãÖ»Ðèº
ô½Ðelf_foobar()À´´¦Àíµµ°¸µÄijһ²¿·Ý(components)¼´¿É,²¢²»ÐèÒª°Ñµµ°¸Ê
µ¼ÊÔڴŵúÉϵÄimage¸ãµÃÒ»ÍÅÂÒ.
ELFµÄÓÅȱµãÓëÉý¼¶ÖÁELFµÈ¼¶ËùÐè¾
ÀúµÄÖÖÖÖÍ´¿à(contortions),ÒÑÔÚELF-HOWTOÄÚÂÛ¼°;ÎÒ²¢²»´òËãÔÚÕâ¶ùÍ¿½¬ºý.E
LF HOWTOÓ¦¸ÃÓëÕâ·ÝÎļþÏà֮ͬ´¦ÓÐͬÑùµÄÖ÷Ìâ²ÅÊÇ.
6.4.2.2. ELF¹²Ïí³Ìʽ¿â
ÈôÏ뽨Á¢libfoo.so³ÉΪ¹²Ïí³Ìʽ¿â,»ù±¾µÄ²½Öè»áÏñÏÂÃæÕâÑù:
$ gcc -fPIC -c *.c
$ gcc -shared -Wl,-soname,libfoo.so.1 -o libfoo.so.1.0 *.o
$ ln -s libfoo.so.1.0 libfoo.so.1
$ ln -s libfoo.so.1 libfoo.so
$ LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH ; export LD_LIBRARY_PATH
Õâ»á²úÉúÒ»¸öÃûΪlibfoo.so.1.0µÄ¹²Ïí³Ìʽ¿â,ÒÔ¼°¸øÓèldÊʵ±µÄÁ¬½á(libfoo.
so)»¹ÓÐʹµÃ¶¯Ì¬ÔØÈë³Ìʽ(dynamic
loader)ÄÜÕÒµ½Ëü(libfoo.so.1).ΪÁ˽øÐвâÊÔ,ÎÒÃǽ«Ä¿Ç°µÄĿ¼¼Óµ½LD_LIBRA
RY_PATHÀï.
µ±Äã½ò½òÀÖµÀì¶³Ìʽ¿âÖÆ×ö³É¹¦Ö®Ê±,
±ðÍüÁ˰ÑËüÒÆµ½Èç/usr/local/libµÄĿ¼µ×ÏÂ,²¢ÇÒÖØÐ½¨Á¢ÕýÈ·µÄÁ¬½á·¾¶.
libfoo.so.1Óëlibfoo.so.1.0µÄÁ¬½á»áÓÉldconfigÒÀÈÕÆÚ²»¶ÏµÄ¸üÐÂ;¾Í´ó²¿·Ýµ
ÄϵͳÀ´Ëµ,ldconfig»áÔÚ¿ª»ú³ÌÐòÖÐÖ´ÐÐ.
libfoo.soµÄÁ¬½á±ØÐëÓÉÊÖ¶¯·½Ê½¸üÐÂ.Èç¹ûÄã¶Ô³Ìʽ¿âËùÓÐ×é³É·Ý×Ó(Èç±êÍ·µµµ
È)µÄÉý¼¶,×ÜÊDZ§³ÖÖøÒ»Ë¿²»¡õµÄ̬¶È(scrupulous),ÄÇ÷á×î¼òµ¥µÄ·½·¨¾ÍÊÇÈÃli
bfoo.so ->
libfoo.so.1;Èç´ËÒ»À´,ldconfig±ã»áÌæÄãͬʱ±£Áô×îеÄÁ¬½á.ÒªÊÇÄãûÓÐÕâ÷á
×ö,Äã×ÔÐÐÉ趨µÄ¶«¶«¾Í»áÔÚÊýÈÕááÔì³ÉÇ§Ææ°Ù¹ÖµÄ»¨Ñù³öÏÖ.µ½Ê±ºò,¿É±ð˵ÎÒÃ
»ÌáÐÑÄã°¡!
$ su
# cp libfoo.so.1.0 /usr/local/lib
# /sbin/ldconfig
# ( cd /usr/local/lib ; ln -s libfoo.so.1 libfoo.so )
6.4.2.3. °æ±¾±àºÅ, sonameÓë·ûºÅÁ¬½á
ÿһ¸ö³Ìʽ¿â¶¼ÓÐÒ»¸ösoname.µ±Á¬½áÆ÷·¢ÏÖËüÕýÔÚËÑѰµÄ³Ìʽ¿âÖÐÓÐÕâÑùµÄÒ»¸
öÃû³Æ,Á¬½áÆ÷±ã»á½«sonameóéÈë(embed)Á¬½áÖеĶþ½øÎ»µµÄÚ,
¶ø²»ÊÇËüÕýÔÚÔË×÷µÄʵ¼ÊµÄµµÃû.ÔÚ³ÌʽִÐÐÆÚ¼ä,¶¯Ì¬ÔØÈë³Ìʽ»áËÑѰӵÓÐsona
meÕâÑùµÄµµÃûµÄµµ°¸,¶ø²»ÊdzÌʽ¿âµÄµµÃû.Òò´Ë,Ò»¸öÃûΪlibfoo.soµÄ³Ìʽ¿â,¾
Í¿ÉÒÔÓÐÒ»¸ölibbar.soµÄsonameÁË.¶øÇÒËùÓÐÁ¬½áµ½libbar.soµÄ³Ìʽ,µ±³Ìʽ¿ªÊ
¼Ö´ÐÐʱ,»áѰÕҵıãÊÇlibbar.soÁË.
ÕâÌýÆðÀ´ºÃÏñÒ»µãÒâÒåҲûÓÐ,µ«ÊÇÕâÒ»µã,¶Ôì¶Á˽âÊý¸ö²»Í¬°æ±¾µÄͬһ¸ö³Ìʽ
¿âÊÇÈçºÎÔÚµ¥Ò»ÏµÍ³ÉϹ²´æ(coexist)µÄÔ
Òò,È´ÊǹؼüÖ®Ô¿.Linux³Ìʽ¿â±ê×¼µÄÃüÃû·½Ê½,±ÈÈç˵ÊÇlibfoo.so.1.2,¶øÇÒ¸ø
Õâ¸ö³Ìʽ¿âÒ»¸ölibfoo.so.1µÄsoname.Èç¹û´Ë³Ìʽ¿âÊǼӵ½±ê×¼³Ìʽ¿âµÄĿ¼µ×
ÏÂ(e.g. /usr/lib),ldconfig»á½¨Á¢·ûºÅÁ¬½álibfoo.so.1 ->
libfoo.so.1.2,ʹÆäÕýÈ·µÄimageÄÜì¶Ö´ÐÐÆÚ¼ä(run-time)ÕÒµ½.ÄãÒ²ÐèÒªÁ¬½áli
bfoo.so -> libfoo.so.1,ʹldÄÜì¶Á¬½áÆÚ¼ä(link-time)ÕÒµ½ÕýÈ·µÄsoname.
ËùÒÔÂÞ,µ±ÄãÐÞÕý³Ìʽ¿âÄÚµÄbugs,»òÊÇÌí¼ÓÁËеĺ¯Êý½øÈ¥(Èκβ»»á¶ÔÏÖ´æµÄ³
ÌʽÔì³É²»ÀûµÄ(adversely)Ó°ÏìµÄ¸Ä±ä),Äã»áÖØ½¨´Ë³Ìʽ¿â,±£ÁôÔ
±¾ÒÑÓеÄsoname,È»áá¸ü¸Ä³Ìʽ¿âµµÃû.¶øµ±Äã¶Ô³Ìʽ¿âµÄ±ä¸ü»áʹµÃÏÖÓеijÌʽ
(binaries)ÖжÏ(break),ÄÇ÷áÄãÖ»ÐèÔö¼ÓsonameÖеıàºÅ---´ËÀýÖÐ,³ÆÐ°汾Ϊ
libfoo.so.2.0,¶øsoname±ä³Élibfoo.so.2.½ô½ÓÖø,ÔÙ½«libfoo.soµÄÁ¬½áתÏòÐÂ
µÄ°æ±¾;ÖÁ´Ë,ÊÀ½çÓÖÔٶȻָ´ÁËºÍÆ½!
ÆäʵÄã²»ÐëÒªÒÔ´ËÖÖ·½Ê½À´Ìæ³Ìʽ¿âÃüÃû,²»¹ýÕâµÄÈ·ÊǸöºÃµÄ´«Í³(convention
).ELFËù¸³ÓèÄãÔÚ³Ìʽ¿âÃüÃûÉϵĵ¯ÐÔ,»áʹµÃÈËÆø´
ºôºôµÄ¸ã²»Çå³þ×´¿ö;ÓÐÕâÑùµÄµ¯ÐÔÔÚ,Ò²²¢²»±íʾÄã¾ÍµÃÈ¥ÓÃËü.
ELF×ܽá:¼ÙÉè¾
ÓÉÄãî£ÖǵĹ۲췢ÏÖÓиö¹ßÀý˵:³Ìʽ¿âÖ÷ÒªµÄÉý¼¶»áÆÆ»µ(break)ÏàÈÝÐÔ(compa
tibility);¶ø´ÎÒªµÄÉý¼¶Ôò¿ÉÄܲ»»á;ÄÇ÷áÒÔÏÂÃæµÄ·½Ê½À´Á¬½á,ËùÓеÄÒ»ÇоͶ¼
»áÏà°²ÎÞÊÂÁË.
gcc -shared -Wl,-soname,libfoo.so.major -o libfoo.so.major.minor
6.4.3. a.out---¾É¾ÉµÄ¸ñʽ~
½¨Á¢¹²Ïí³Ìʽ¿âµÄ±ãÀûÐÔ(ease)ÊÇÉý¼¶ÖÁELFµÄÖ÷ÒªÔ
ÒòÖ®Ò».ÄÇÒ²ÊÇ˵,a.out¿ÉÄÜ»¹ÊÇÓÐÓô¦ÔÚµÄ.ÉÏftpվȥץftp://tsx-11.mit.ed
u/pub/linux/packages/GCC/src/tools-2.17.tar.gz;½âѹËõááÄã»á·¢ÏÖÓÐ20Ò³µ
ÄÎļþ¿ÉÒÔÂýÂýµÄ¶ÁÁ¨.ÎҺܲ»Ï²»¶×Ô¼ºµ³Åɵ᫼û(partisan)±íÏÖµÃÄÇ÷áµÄÁÜÁ§
¾¡ÖÂ,¿ÉÊÇ´ÓÉÏÏÂÎļä,Ó¦¸ÃÒ²¿ÉÒÔºÜÇå³þµÄÐá³öÎÒ´ÓÀ´²»ÄÃʯͷÔÒ×Ô¼ºµÄ½ÅµÄÆ¢
Æø°É!:-)
6.4.3.1. ZMAGIC vs QMAGIC
QMAGICÊÇÒ»ÖÖÀàËÆ¾É¸ñʽµÄa.out(Òà³ÆÎªZMAGIC)µÄ¿ÉÖ´Ðеµ
¸ñʽ,ÕâÖÖ¸ñʽ»áʹµÃµÚÒ»¸ö·ÖÒ³ÎÞ·¨map.µ±0-4096µÄ¡õΧÄÚûÓÐmapping´æÔÚʱ
,Ôò¿ÉÔÊÐíNULL dereference trapping¸ü¼ÓµÄÈÝÒ×.Ëù²úÉúµÄ±ß½çЧӦ(side
effect)ÊÇÄãµÄÖ´Ðеµ»á±È½ÏС(´óÔ¼ÊÇ1K×óÓÒ).
Ö»Óм´½«×÷·ÏµÄÁ¬½áÆ÷ÓÐÖ§Ô®ZMAGIC,Ò»°ëÒÑÂñÈë¹×²ÄµÄÁ¬½áÆ÷ÓÐÖ§Ô®ÕâÁ½ÖÖ¸ñÊ
½;¶øÄ¿Ç°µÄ°æ±¾½öÖ§Ô®QMAGIC¶øÒÑ.ÊÂʵÉÏ,ÕⲢûÓжà´óµÄÓ°Ïì,ÄÇÊÇÒòΪĿǰµ
ĺËÐÄÁ½ÖÖ¸ñʽ¶¼ÄÜÖ´ÐÐ.
*file*ÃüÁîÓ¦¸Ã¿ÉÒÔÈ·ÈϳÌʽÊDz»ÊÇQMAGICµÄ¸ñʽµÄ.
6.4.3.2. µµ°¸ÅäÖÃ(File Placement)
Ò»a.out(DLL)µÄ¹²Ïí³Ìʽ¿â°üº¬Á½¸öÕæÊµµÄµµ°¸ÓëÒ»¸ö·ûºÅÁ¬½á.¾Í*foo*Õâ¸öÓÃ
ì¶Õû·ÝÎļþ×öΪ¡õÀýµÄ³Ìʽ¿â¶øÑÔ,ÕâЩµµ°¸»áÊÇlibfoo.saÓëlibfoo.so.1.2;·û
ºÅÁ¬½á»áÊÇlibfoo.so.1,¶øÇÒ»áÖ¸Ïòlibfoo.so.1.2.ÕâЩÊÇ×öʲ÷áÓõÄ?
ÔÚ±àÒëʱ,
ld»áѰÕÒlibfoo.sa.ÕâÊdzÌʽ¿âµÄ*stub*µµ°¸,¶øÇÒº¬ÓÐËùÓÐÖ´ÐÐÆÚ¼äÁ¬½áËùÐèµ
ÄexportedµÄ×ÊÁÏÓëÖ¸Ïòº¯ÊýµÄÖ¸±ê.
Ö´ÐÐÆÚ¼ä,¶¯Ì¬ÔØÈë³Ìʽ»áѰÕÒlibfoo.so.1.Õâ½ö½öÊÇÒ»¸ö·ûºÅÁ¬½á,¶ø²»ÊÇÕæÊµ
µÄµµ°¸,¹Ê³Ìʽ¿â¿É¸üгɽÏеÄÇÒÒÑÐÞÕý´íÎóµÄ°æ±¾,¶ø²»»áËð»ÙÈκδËʱÕýÔÚ
ʹÓô˳Ìʽ¿âµÄÓ¦ÓóÌʽ.ÔÚаæ---±ÈÈç˵libfoo.so.1.3---ÒÑÍêÕû³ÊÏÖʱ,ldc
onfig»áÒÔÒ»¼«Î¢Ð¡µÄ²Ù×÷,½«Á¬½áÖ¸Ïòеİ汾,ʹµÃÈκÎÔ
±¾Ê¹ÓþɰæµÄ³Ìʽ²»»á¸Ðµ½Ë¿ºÁµÄ²»ÔÃ.
DLL³Ìʽ¿â(ÎÒÖªµÀÕâÊÇÎÞνµÄ·´¸²(tautology)---ËùÒÔ¶ÔÎÒÌá³ö¸æËß°É!)ͨ³£»á
±ÈËüÃǵľ²Ì¬¸±±¾(static
counterparts)ÒªÀ´µÃ´ó¶àÁË.ËüÃÇÊÇÒÔ*¶´(holes)*µÄÐÎʽÀ´±£Áô¿Õ¼äÒÔ±ãÈÕááµ
ÄÀ©³ä.ÕâÖÖ*¶´*¿ÉÒÔ²»Õ¼ÓÃÈκεĴŵú¿Õ¼ä.Ò»¸ö¼òµ¥µÄcpºô½Ð,»òÊÇʹÓÃmakeho
le³Ìʽ,¾Í¿ÉÒÔ´ïµ½ÕâÑùЧ¹û(achieve).ÒòΪËüÃǵÄλַÊǹ̶¨ÔÚͬһλÖÃÉÏ,Ëù
ÒÔÔÚ½¨Á¢³Ìʽ¿âáá,Äã¿ÉÒÔ°ÑËüÃÇÄõô.ǧÍò²»ÒªÊÔÖø¶á×ßELFµÄ³Ìʽ¿â.
6.4.3.3. ``libc-lite''?
libc-liteÊÇÇáÁ¿¼¶(light-weight)µÄlibc°æ±¾.¿ÉÓÃÀ´´æ·ÅÔڴŵúƬÉÏ,Óë
Ìæ´ó²¿·ÝµÍ΢µÄ(menial)UNIXÈÎÎñÊÕβ(suffice).ËüûÓаüº¬curses, dbm,
termcapµÈµÈµÄ³ÌʽÂë.Èç¹ûÄãµÄ/lib/libc.so.4ÊÇÁ¬½áµ½Ò»¸öliteµÄlibc,ÄÇ÷á½
¨ÒéÄãÒÔÍêÕûµÄ°æ±¾È¡´úËü.
6.4.4. Á¬½á:³£¼ûµÄÎÊÌâ
°ÑÄãÁ¬½áʱËùÔâÓöµÄÎÊÌâ¼Ä¸øÎÒ!ÎÒ¿ÉÄÜʲ÷áÊÂÒ²²»»á×ö,µ«ÊÇÖ»ÒªÀÛ»ýÁË×ã¹»µÄ
ÊýÁ¿, ÎÒ»á°ÑËüÃÇдÆðÀ´*.
ÄãÏë¹²Ïí,ƫƫ³ÌʽȴÁ¬½á³É¾²Ì¬µÄ!
¼ì²éÄãÌṩ¸øldµÄÁ¬½áÊÇ·ñÕýÈ·,ʹldÄÜÕÒµ½Ã¿Ò»¸ö¶ÔÓ¦µÄ¹²Ïí³Ìʽ¿â.¾
ÍELF¶øÑÔ,ÕâÊÇÖ¸Ò»¸ö·ûºÅÁ¬½álibfoo.so,Á¬½áÖÁimage;¾Ía.out¶øÑÔ,¾Í
ÊÇlibfoo.saµµÁË.ºÜ¶àÈ˽«ELF binutils
2.5Éý¼¶ÖÁ2.6Ö®áá,¾Í²úÉúÁËÕâ¸öÎÊÌâ---ÔçÆÚµÄ°æ±¾ËÑѰ¹²Ïí³Ìʽ¿âʱ½
ÏÓÐÖÇ»Û,ËùÒÔ²¢Ã»Óн«ËùÓеÄÁ¬½á½¨Á¢ÆðÀ´.ááÀ´,ΪÁËÓëÆäËüµÄ¼Ü¹¹ÏàÈ
Ý,ÕâÏî³äÂúÖǻ۵ÄÐÐΪ±»È˸øÉ¾³ýµôÁË,ÁíÍâ,ÕâÑùµÄ*ÖÇ»Û*ÅжϴíÎóµÄ»
úÂÊÏ൱¸ß,ËùÔì³ÉµÄÂé·³±ÈËüËù½â¾öµÄÎÊÌ⻹¶à,ËùÒÔÁôÖøÒ²ÊǺ¦È˾«,²
»Èç¹éÈ¥Ùâ!
The DLL tool `mkimage' fails to find libgcc, or
´Ólibc.so.4.5.xÖ®áá,libgccÒѲ»ÔÙÊǹ²ÏíµÄ¸ñʽ.Òò´Ë,Äã±ØÐëÔÚ*-lgc
c*³öÏÖÖ®´¦ÒÔ`gcc
-print-libgcc-file-name`È¡´ú(ÍêÕûµÄµ¹µ¥ÒýºÅ(back-quotes)).ÁíÍâ,
ɾ³ýËùÓÐ/usr/lib/libgcc*µÄµµ°¸.ÕâµãºÜÖØÒªÁ¨.
__NEEDS_SHRLIB_libc_4 multiply defined messages
ÊÇͬÑùµÄÎÊÌâËùÔì³ÉµÄÁíÒ»ÖÖ½á¹û.
``Assertion failure'' message when rebuilding a DLL ?
ÕâÒ»ÌõÉñÃØµÄ(cryptic)ѶϢ×îÓпÉÄܵÄÔÒòÊÇ,ÔÚÔ
ʼµÄjump.varsµµ°¸ÄÚ,ÓÉì¶±£ÁôµÄ¿Õ¼äÌ«ÉÙ, ÒÔÖÂì¶Ôì³ÉÆäÖÐÒ»¸öjump
table
slotsÒçÂú(overflow).Äã¿ÉÒÔÖ´ÐÐtools-2.17.tar.gzÌ×¼þËùÌṩµÄ`get
size'ÃüÁî,¶¨³öËùÓÐÏÓÒÉ·¸(culprit(s))µÄ×Ù¼£.¿ÉÄÜΨһµÄ½â¾ö·½·¨ÊÇ
,½â³ý(bump)´Ë³Ìʽ¿âÖ÷ÒªµÄ°æ±¾±àºÅ,Ç¿ÆÈËü»Øµ½²»ÏàÈݵÄÄê´ú(be
backward incompatible).
ld: output file needs shared library libc.so.4
ͨ³£ÕâÊÇ·¢ÉúÔÚµ±ÄãÁ¬½áµÄ³Ìʽ¿â²»ÊÇlibc(ÈçX³Ìʽ¿â),¶øÇÒÔÚÃüÁîÁÐÓ
ÃÁË-gµÄ²ÎÊý,ȴûÓÐÒ»²¢Ê¹ÓÃ-static,Ëù·¢³öµÄ´íÎóѶϢ.
¹²Ïí³Ìʽ¿âµÄ.sa
stubsͨ³£ÓÐÒ»¸ö䶨ÒåµÄ·ûºÅ_NEEDS_SHRLIB_libc_4;¶øÕâÒ»µã¿É½åÓÉl
ibc.sa
stubÀ´½â¾ö.È»¶ø,ÒÔ-gÀ´±àÒëʱ,»áʹµÃÁ¬½áÒÔlibg.a»òlibc.aÀ´½áÊø;Ò
ò´ËÕâ¸ö·ûºÅÒ»Ö±¾ÍûÓнâ¾ö,Ò²¾Í»áµ¼ÖÂÉÏÃæµÄ´íÎóѶϢÁË.
×ÜÖ®,ÒÔ-gµÄÆìºÅ±àÒëʱ±ðÍüÁ˼ÓÉÏ-static,²»È»¾Í±ðÓÃ-gÀ´Á¬½á.ͨ³£,
ÒÔ-g±àÒë¸÷¸ö¶ÀÁ¢µÄµµ°¸Ê±,Ëù»ñµÃµÄ³ý´í×ÊѶÒѾ
×ã¹»,Á¬½áʱ¾Í¿ÉÒÔ²»ÐèÒªËüÁË.
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : Á¬½á(Linking)
Previous: Debugging and Profiling
Next: ¶¯Ì¬ÔØÈë(Dynamic Loading) The Linux GCC HOWTOÖÐÒë°æV0.1 :
¶¯Ì¬ÔØÈë(Dynamic Loading)
Previous: Á¬½á(Linking)
Next: Óë·¢Õ¹ÈËÊ¿ÁªÂç
_________________________________________________________________
7. ¶¯Ì¬ÔØÈë(Dynamic Loading)
ÕâÒ»Õ½ÚĿǰÊǼò¶ÌÁËÒ»µã;µ±ÎÒÂÓ¾¡ELF
HOWTOʱ,¾ÍÊÇÕⲿ·ÝÔÙ¶ÈÀ©Õ¹µÄʱºòÁË.
7.1. »ù±¾¸ÅÄî
LinuxÓй²Ïí³Ìʽ¿â,Èç¹û֮ǰÄãÒÑ×øÖø¶ÁÍêÉÏÒ»Õ½Ú,Ïë±ØÏÖÔÚÒ»Ìýµ½ÏñÕâÑùµÄË
µ´Ê,±ã»áÁ¢¿Ì¸Ðµ½Í·»è.ÓÐһЩÕÕ¹ßÀý¶øÑÔÊÇÔÚÁ¬½áʱÆÚ±ã¸ÃÍê³ÉµÄ¹¤×÷(matchi
ng-names-to-places),±ØÐëÑÓ³Ùµ½ÔØÈëʱÆÚ(load-time)²ÅÄÜÍê³É.
7.2. ´íÎóѶϢ(Error messages)
°ÑÄãÁ¬½áµÄ´íÎó¼Ä¸øÎÒ!ÎÒ²»»á×öÈκεÄÊÂ,²»¹ýÎÒ¿ÉÒÔ°ÑËüÃÇдÆðÀ´**
can't load library: /lib/libxxx.so, Incompatible version
(a. out only)
ÕâÊÇÖ¸ÄãûÓÐxxx³Ìʽ¿âµÄÕýÈ·µÄÖ÷Òª°æ±¾.¿É±ðÒÔÎªËæËæ
±ã±ãŪ¸öÁ¬½áµ½ÄãĿǰӵÓеİ汾¾Í¿ÉÒÔÁË,Èç¹ûÐÒÔ˵ϰ,
¾ÍÖ»»áÔì³ÉÄãµÄ³Ìʽ·ÖÒ³´íÎó¶øÒÑ.ȥץеİ汾.ELFÀàËÆµÄÇé¿ö»áÔì³É
ÏñÏÂÃæÕâÑùµÄѶϢ:
ftp: can't load library 'libreadline.so.2'
warning using incompatible library version xxx
(a. out
only)ÄãµÄ³Ìʽ¿âµÄ´ÎÒª°æ±¾±ÈÆðÕâÖ§³ÌʽÓÃÀ´±àÒëµÄ»¹Òª¾É.³ÌʽÒÀÈ»¿
ÉÒÔÖ´ÐÐ.Ö»ÊÇ¿ÉÄÜÀ²!ÎÒÏë,Éý¸ö¼¶Ó¦¸Ãûʲ÷áÉ˺¦°É!
7.3. ¿ØÖƶ¯Ì¬ÔØÈëÆ÷µÄÔË×÷
ÓÐÒ»×é»·¾³±äÊý»áÈö¯Ì¬ÔØÈëÆ÷ÓÐËù·´Ó¦.´ó²¿·ÝµÄ»·¾³±äÊý¶ÔlddµÄÓÃ;Ҫ±ÈÆð
¶ÔÒ»°ãusersµÄ»¹ÒªÀ´µÃ¸ü¶à.¶øÇÒ¿ÉÒԺܷ½±ãµÄÉ趨³ÉÓÉlddÅäºÏ¸÷ÖÖ²ÎÊýÀ´Ö´Ð
Ð.ÕâЩ±äÊý°üÀ¨
* LD_BIND_NOW --- Õý³£À´½²,º¯ÊýÔÚºô½Ð֮ǰÊDz»»áÈóÌʽѰÕÒ(looked
up)µÄ.É趨Õâ¸öÆìºÅ»áʹµÃ³Ìʽ¿âÒ»ÔØÈë,ËùÓеÄѰÕÒ(lookups)±ã»á·¢Éú,Í
¬Ê±Ò²Ôì³ÉÆðʼµÄʱ¼ä(startup
time)½ÏÂý.µ±ÄãÏë²âÊÔ³Ìʽ,È·¶¨ËùÓеÄÁ¬½á¶¼Ã»ÓÐÎÊÌâʱ,ÕâÏîÆìºÅ¾Í±äµÃ
ºÜÓÐÓÃ.
* LD_PRELOAD
¿ÉÒÔÉ趨һ¸öµµ°¸,ʹÆä¾ßÓÐ*¸²¸Ç*(overriding)º¯Êý¶¨ÒåµÄÄÜÁ¦.ÀýÈç,Èç¹
ûÄãÒª²âÊÔ¼ÇÒäÌå·ÖÅäµÄ·½ÂÔ(strategies),¶øÇÒ»¹ÏëÖû»*malloc*,ÄÇ÷áÄã¿
ÉÒÔдºÃ×¼±¸Ìæ»»µÄ¸±³Ìʽ(routine),²¢°ÑËü±àÒë³Émallolc.,È»áá:
$ LD_PRELOAD=malloc.o; export LD_PRELOAD
$ some_test_program
LD_ELF_PRELOAD Óë LD_AOUT_PRELOAD
ºÜÀàËÆ,µ«ÊǽöÊÊÓÃì¶ÕýÈ·µÄ¶þ½øÎ»ÐÍ̬.Èç¹ûÉ趨ÁË
LD_something_PRELOAD Óë LD_PRELOAD ,±È½ÏÃ÷È·µÄÄÇÒ»¸ö»á±»Óõ½.
* LD_LIBRARY_PATH
ÊÇÒ»Á¬´®ÒԷֺŸôÀëµÄĿ¼Ãû³Æ,ÓÃÀ´ËÑѰ¹²Ïí³Ìʽ¿â.¶Ôld¶øÑÔ,²¢Ã»ÓÐÈκ
εÄÓ°Ïì;ÕâÏîÖ»ÓÐÔÚÖ´ÐÐÆÚ¼ä²ÅÓÐÓ°Ïì.ÁíÍâ,¶ÔÖ´ÐÐsetuidÓësetgidµÄ³Ìʽ
¶øÑÔ,ÕâÒ»ÏîÊÇÎÞЧµÄ.¶øLD_ELF_LIBRARY_PATHÓëLD_AOUT_LIBRARY_PATHÕâÁ
½ÖÖÆìºÅ¿É¸ù¾Ý¸÷±ðµÄ¶þ½øÎ»ÐÍʽ·Ö±ðµ¼Ïò²»Í¬µÄËÑѰ·¾¶.Ò»°ãÕý³£µÄÔË×÷
ÏÂ,²»Ó¦¸Ã»áÓõ½LD_LIBRARY_PATH;°ÑÐèÒªËÑѰµÄĿ¼¼Óµ½/etc/ld.so.conf
/Àï;È»ááÖØÐÂÖ´ÐÐldconfig.
* LD_NOWARN ½öÊÊÓÃì¶a.out.Ò»µ©É趨ÁËÕâÒ»Ïî(LD_NOWARN=true; export
LD_NOWARN),Ëü»á¸æËßÔØÈëÆ÷±ØÐë´¦Àífatal-warnings(ÏñÊÇ´ÎÒª°æ±¾²»ÏàÈÝ
µÈ)µÄ¾¯¸æÑ¶Ï¢.
* LD_WARN ½öÊÊÓÃì¶ELF.É趨ÕâÒ»Ïîʱ,Ëü»á½«Í¨³£ÊÇÖÂÃüѶϢµÄ"Can*t find
library"ת»»³É¾¯¸æÑ¶Ï¢.¶ÔÕý³£µÄ²Ù×÷¶øÑÔ,ÕⲢûÓжà´óµÄÓô¦,¿ÉÊǶÔl
dd¾ÍºÜÖØÒªÁË.
* LD_TRACE_LOADED_OBJECTS
½öÊÊÓÃì¶ELF.¶øÇÒ»áʹµÃ³ÌʽÒÔΪËüÃÇÊÇÓÉlddËùÖ´ÐеÄ:
$ LD_TRACE_LOADED_OBJECTS=true /usr/bin/lynx
libncurses.so.1 => /usr/lib/libncurses.so.1.9.6
libc.so.5 => /lib/libc.so.5.2.18
7.4. ÒÔ¶¯Ì¬ÔØÈë׫д³Ìʽ
Èç¹ûÄãºÜÊìϤSolaris
2.xËùÖ§Ô®µÄ¶¯Ì¬ÔØÈëµÄ¹¤×÷µÄ»°,Äã»á·¢ÏÖLinuxÔÚÕâµãÉÏÓëÆä·Ç³£µÄÏà½ü.ÕâÒ»
²¿·ÝÔÚH.J.LuµÄELF³ÌʽÉè¼ÆÎļþÄÚÓëdlopen(3)µÄmanual
page(¿ÉÒÔÔÚld.soµÄÌ×¼þÉÏÕÒµ½)ÉÏÓй㷺µÄº¬¸Ç(cover).ÕâÀïÓиö²»´íµÄ¼òµ¥¡
õÀý:ÒÔ-ldlÁ¬½á.
#include <dlfcn.h>
#include <stdio.h>
main()
{
void *libc;
void (*printf_call)();
if(libc=dlopen("/lib/libc.so.5",RTLD_LAZY))
{
printf_call=dlsym(libc,"printf");
(*printf_call)("hello, world\n");
}
}
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : ¶¯Ì¬ÔØÈë(Dynamic Loading)
Previous: Á¬½á(Linking)
Next: Óë·¢Õ¹ÈËÊ¿ÁªÂç The Linux GCC HOWTOÖÐÒë°æV0.1 : Óë·¢Õ¹ÈËÊ¿ÁªÂç
Previous: ¶¯Ì¬ÔØÈë(Dynamic Loading)
Next: ½áÓï
_________________________________________________________________
8. Óë·¢Õ¹ÈËÊ¿ÁªÂç
8.1. Bug±¨±í
°ÑÎÊÌâдÏÂÀ´.ÕâÊÇÕë¶ÔLinuxµÄ,Òà»òÊÇgccÔÚÆäËüϵͳÉÏËù·¢ÉúµÄÎÊÌâ.Óëkerne
lµÄ°æ±¾Ïà¹ØÂð?»òÕßÊdzÌʽ¿âµÄ°æ±¾?Èç¹û¸ÄÓþ²Ì¬·½Ê½Á¬½á,ÎÊÌâÊDz»ÊǾÍÏûʧ
ÁË?Äã¿ÉÒÔ½Ú¼һС¶Î³ÌʽÀ´Õ¹Ê¾ÕâÖ»bugÂð?
µ±Äã×öÁËÕâЩÊÂÇéÖ®áá,Ä㽫»áÖªµÀ³ÌʽÄÚµÄbugsÊÇʲ÷á.¾Ígcc¶øÑÔ,bug±¨±í³ÌÐ
òÊÇÒÔinfoµµÀ´ËµÃ÷µÄ.Èç¹ûÊÇld.so»òÊÇC,maths³Ìʽ¿â,½«email¼Äµ½linux-gcc@
vger.rutgers.edu.Èç¹û¿ÉÄܵϰ,°üº¬Ò»Ö§×Ô¼º×Ô×ãµÄС³ÌʽÒÔչʾÕâ¸öbug,¶ø
ÇÒ¸½ÉÏ˵Ã÷,ÃèÊöÄãÏëÒªÈÃÕâÖ§³Ìʽ×öЩʲ÷áÓëʵ¼ÊÉÏËüÓÖ×öÁËЩʲ÷á.
8.2. ÐÖú·¢Õ¹
Èç¹ûÄãÏëÒª°ïæ·¢Õ¹gcc»òÊÇC³Ìʽ¿â,µÚÒ»¼þʱãÊǼÓÈëlinux-gcc@vger.rutger
s.eduÓʼþ±íÁÐ(mailing list).Èç¹ûÄãÖ»ÊÇÏë¿´¿´mailing
listÔÚÌÖÂÛЩʲ÷á,ÕâÀïÓÐÒ»¸ö±íÁеÄarchives,λì¶http://homer.ncm.com/lin
ux-gcc/.½ÓÏÂÀ´µÄÊÂ,¾Í¿´ÄãÏë×öʲ÷áÁË.
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : Óë·¢Õ¹ÈËÊ¿ÁªÂç
Previous: ¶¯Ì¬ÔØÈë(Dynamic Loading)
Next: ½áÓï The Linux GCC HOWTOÖÐÒë°æV0.1 : ½áÓï
Previous: Óë·¢Õ¹ÈËÊ¿ÁªÂç
Next: Ë÷Òý
_________________________________________________________________
9. ½áÓï
9.1. ÃûÈ˰ñ
Only presidents, editors, and people with tapeworms have the right
to use the editorial ``we''.
(Mark Twain)
Õâ·ÝHOWTOÎļþ¼¸ºõÍêÈ«¸ùÖ²ì¶Mitchum DsouzaµÄGCC-FAQ;
ÎļþÄڴ󲿷ݵÄ×ÊѶ(not to mention a reasonable amount of the
text)ÊÇÖ±½ÓÀ´×Ôì¶GCC-FAQµÄ.
Õâ·ÝHOWTOÎļþÓõ½µÄµÚÒ»È˳ƴúÃû´Ê,¿ÉÊÓΪÎÒÃÇÁ½ÈËÆäÖÐÒ»¸ö;ͨ³£,ÒªÊÇÓÐÈË
˵"ÎÒ»¹Ã»ÓвâÊÔ¹ýÕâЩ;Èç¹ûËüÉÕÁË(toast)ÄãµÄÓ²µú/ϵͳ/Åäż,¿É±ð¹ÖÎÒ!",Ä
ÇÕâÑùµÄ»°ÊÊÓÃì¶ÎÒÁ©ÉíÉÏ.
¶ÔÕâ·ÝÎļþÓй±Ï×µÄÃûÈËÑÅÊ¿ÈçÏÂËùÁÐ(ÒÔÃû×ÖµÄASCIIÂëµÄ˳Ðò): Andrew
Tefft, Axel Boldt, Bill Metzenthen, Bruce Evans, Bruno Haible, Daniel
Barlow, Daniel Quinlan, David Engel, Dirk Hohndel, Eric Youngdale,
Fergus Henderson, H.J. Lu, Jens Schweikhardt, Kai Petzke, Michael
Meissner, Mitchum DSouza, Olaf Flebbe, Paul Gortmaker, Rik Faith,
Steven S. Dick, Tuomas J Lukka, µ±È»»¹ÓÐLinux
Torvalds,ûÓÐÁËËû,ÕâÕû¸öÔ˶¯¾Í»á±äµÃÒ»µãÒâÒåҲûÓÐÁË,ËùÒÔ²»¿ÉÄÜÈÃËû¹Âµ
¥µÄ.:-)
Çë²»Òª¾õµÃÓÐÈκεÄð·¸Ö®´¦,Èç¹ûÄúµÄÃû×ÖûÓгöÏÖÔÚÕâ¶ù,¶øÄú¶ÔÕâ·ÝÎļþ(H
OWTO»òÊÇFAQ)ÓÖÔø¾Óйý¹±Ï׵ϰ,Çëemail¸øÎÒ,ÎÒ»á¸ÄÕý¹ýÀ´µÄ.
9.2. ·Òë
µ½Ä¿Ç°ÎªÖ¹,Õâ·ÝÎļþ»¹Ã»ÓÐÒÑÖªµÄ·
Òë°æ³öÏÖ.Èç¹ûÄãÏ£ÍûÉúÒ»¸ö³öÀ´,Ç뾡¹ÜÈ¥×ö,²»¹ýÒ»¶¨µÃ¸æËßÎÒÏà¹ØµÄÊÂÒË.ÎÒ
½²µÄÓïÑÔ»áÊÇÄãÏëÒª·
µÄÓïÑÔ,ÄÇ»úÂÊ(ºÜÒź¶)Ö»Óкü¸°Ù·ÖÖ®Ò»,²»¹ý»¹ÊÇÏȰÑÕâ°ÚÒ»ÅÔ°É!²»¹ÜÊÇʲ÷
᷽ʽ,ÎÒ¶¼»áºÜÀÖÒâ°ïæµÄ.
9.3. »¶ÓÈκεĻØÀ¡(Feedback)
¼ÄПøÎÒdan@detached.demon.co.uk.ÎÒµÄPGP public key (ID 5F263625)
¿ÉÔÚÎҵĺæÅ༦web pagesÉÏʹÓÃ, Èç¹ûÄã¾õµÃÊÂÇéÓбØÒª±£Ãܵϰ.
9.4. ºÏ·¨µÄÐÐåɹ涨
All trademarks used in this document are acknowledged as being owned
by their respective owners.
This document is copyright (C) 1996 Daniel Barlow
<dan@detached.demon.co.uk> It may be reproduced and distributed in
whole or in part, in any medium physical or electronic, as long as
this copyright notice is retained on all copies. Commercial
redistribution is allowed and encouraged; however, the author would
like to be notified of any such distributions.
All translations, derivative works, or aggregate works incorporating
any Linux HOWTO documents must be covered under this copyright notice.
That is, you may not produce a derivative work from a HOWTO and impose
additional restrictions on its distribution. Exceptions to these rules
may be granted under certain conditions; please contact the Linux
HOWTO coordinator at the address given below.
In short, we wish to promote dissemination of this information through
as many channels as possible. However, we do wish to retain copyright
on the HOWTO documents, and would like to be notified of any plans to
redistribute the HOWTOs.
If you have questions, please contact Greg Hankins, the Linux HOWTO
coordinator, at gregh@sunsite.unc.edu via email.
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : ½áÓï
Previous: Óë·¢Õ¹ÈËÊ¿ÁªÂç
Next: Ë÷Òý The Linux GCC HOWTOÖÐÒë°æV0.1 : Ë÷Òý
Previous: ½áÓï
Next: The Linux GCC HOWTOÖÐÒë°æV0.1
_________________________________________________________________
10. Ë÷Òý
ÒÔ·ÇÎÄÊý×ÖµÄ(non-alphabetical)×ÖÔªÆðʼµÄÈë¿Ú´¦(entries),ÊÇÒÔASCIIÂëµÄË
³ÐòÅÅÁеÄ.
* -fwritable-strings 39 56
* /lib/cpp 16
* a.out 1
* ar 10
* as 8
* <asm/*.h> 19
* atoi() 40
* atol() 41
* binaries too big 63 65 77
* chewing gum 3
* cos() 68
* debugging 59
* dlopen() 82
* dlsym() 83
* documentation 4
* EINTR 52
* elf 0 71
* execl() 57
* fcntl 47
* FD_CLR 44
* FD_ISSET 45
* FD_SET 43
* FD_ZERO 46
* file 2
* <float.h> 20
* gcc 6
* gcc -fomit-frame-pointer 61
* gcc -g 60
* gcc -v 14
* gcc, bugs 15 28 29 84
* gcc, flags 13 25 26
* gdb 64
* header files 17
* interrupted system calls 51
* ld 9
* LD_* environment variables 80
* ldd 81
* libc 7
* libg.a 62
* libgcc 79
* <limits.h> 21
* lint 58
* <linux/*.h> 18
* manual pages 5
* <math.h> 70
* maths 69
* mktemp() 55
* optimisation 27
* QMAGIC 76
* segmentation fault 30 54
* segmentation fault, in GCC 33
* select() 50
* SIGBUS 34
* SIGEMT 35
* SIGIOT 36
* SIGSEGV 31 53
* SIGSEGV, in gcc 32
* SIGSYS 38
* SIGTRAP 37
* sin() 67
* soname 73
* sprintf() 42
* statically linked binaries, unexpected 66 78
* <stdarg.h> 23
* <stddef.h> 24
* strings 11
* <sys/time.h> 48
* <unistd.h> 49
* <varargs.h> 22
* version numbers 12 74
* weird things 72
* ZMAGIC 75
_________________________________________________________________
The Linux GCC HOWTOÖÐÒë°æV0.1 : Ë÷Òý
Previous: ½áÓï
Next: The Linux GCC HOWTOÖÐÒë°æV0.1
--
¡ù À´Ô´:¡¤BBS ˮľÇ廪վ bbs.net.tsinghua.edu.cn¡¤[FROM: ie0.ie.ac.cn]
BBSˮľÇ廪վ¡Ã¾«»ªÇø