📄 readme
字号:
What's here, what you've got, What's working, what's not. Rob Gingell -- April 1991The dynamic linking/shared libraries stuff is arrayed in the distributionas listed below. It's pulled "as is" from our source tree and trimmed backa bit to remove the extraneous stuff. ./bin/ The command "ldd", which (when given a dynamically linked program) lists what it depends upon. ./lang/ld/ The source for "ld". I've gotten rid of things like "source browser" support and the like, so that it's basically our version of the BSD 4.x "ld" + dynamic linking. If you want to do more cleaning up, you can probably simply delete the file extra.c and incl.c along with the references to their entry points in ld.c. These things handle "#ident" string support and dbx include files, respectively. The latter is rumored to have bugs for extremely large files. ./lang/rtld/ The source of "ld.so" -- the dynamic loader. The Makefile supplied assumes that there's a libc_pic.a -- which is an archive of the -pic objects that make up the C library. This is because ld.so's construction involves linking against this archive in order to pick up -pic'ized versions of system call stubs and one or two library functions. You can probably fake this out with a few hand-written routines to get started. ./lib/ The crt0 files for SPARC and the M68K Suns. ./man/ "man" page sources for everything here as well as auxiliary things. ./usr.lib/ Source for "libdl" (which isn't much.)There's also a copy of the tutorial pages from one of our manuals includedwith the donation letter. We're not expecting you to be able to use thetext of this literally, in part because it's not all that great and in partbecause there's a context for it. It's basically a cut-and-paste job ofthe 1987 USENIX paper that originally described this, along with some funfacts about how to build .sa files and the like.While it's not expected that these will be immediately useful to you, theydid compile and link and work (except for ld.so, which needs the C libraryroutines described above), in the source tree I'm providing. Note that thisuses Sun's "make".Here's a summary listing of the known problems: - _init/_fini support does not really exist; - ld can write an output file even when there are errors (1050797); - some really trivial .so's can cause the loader to bomb (1041946); - there's an uninitialized variable (1050594).The ()-enclosed numbers reference Sun bug reports, the text of which isattached to this. The dlopen(3) man page talks about the use of _init/_fini.It lies. We did actually build the support at one point, but through aSNAFU it never got integrated. However, we didn't go rectify it right awaybecause as it turned out the infrastructure really needed to make this workjust isn't here. crt0's have to call an _init too, but they don't. Andthe loader (or someone) would have to be taught how to construct onefrom (say) C++ static construction routines -- but it doesn't. My advice,rip the reference out of the man page. If or when the rest of the infrastructure gets put into place, adding the code to do this ispretty trivial.Here are things that I would suggest be ideal things to "be improved"for inclusion in 4.4BSD, in priority order. - Do what SVR4 (and I think OSF) do for program start-up. In SVR4, rather than embed the bootstrap with every dynamically linked program through crt0 as SunOS 4.x does, extend the notion of "interpreter" to binary programs. BSD supports the #! form of "interpreter" specification for scripts. SVR4 took this and (in the context of a new object file format) allowed a binary to specify its "interpreter." This way, the mechanics of invoking the loader could be eliminated from all the programs. Although we never had to, if we ever decided we wanted to change those mechanics it would have been a royal pain with the approach in SunOS. A way you might do this is by having dynamically linked executables have different magic numbers, and either have the kernel interpret the numbers as "use ld.so" or else provide a field that holds the specification of the interpreter. (The latter is what's done with ELF files in SVR4.) - Another improvement in SVR4 over what's in SunOS 4.x is the _DYNAMIC structure is specified as a list of attribute-value pairs. This simplifies evolution of the interface a little bit. - The use of .sa files is, of course, a crock. But there's no alternative if a constraint is "use the a.out format." If you have an object file format that tells you some type and size information (as SVR4 does with ELF), you can get rid of .sa files. I'll be glad to talk with you (or whomever) more about how to pursue this if you like. This is the hardest of the changes listed here, which is why I've listed it last. In terms of "customer happiness", it'd probably be the most important. Bug Id: 1050797 Product: sunos Category: compiler Subcategory: linker Release summary: 4.1 Bug/Rfe: bug State: dispatched Synopsis: linker generates final output file upon errors during link. Keywords: link, linker, a.out Severity: 3 Priority: 3 Responsible Manager: gingell Description:Linker creates final output file even if there's linkageerrors like an unresolved symbols. This can affect makeby causing it to think that target is up to date.To Reproduce:1) Create the following files.==================================================babyblues:135 !moremore *.c::::::::::::::t1.c::::::::::::::main(){ printf("\nMain"); a();}::::::::::::::t2.c::::::::::::::b(){ printf("\nIn t2.c b()");}babyblues:136 babyblues:136 more Makefilet: t1.o t2.o cc -o t t1.o t2.ot1.o: cc -c t1.c t2.o: cc -c t2.c2) Run make.==================================================babyblues:139 makecc -c t1.ccc -c t2.ccc -o t t1.o t2.old: Undefined symbol _a *** Error code 2make: Fatal error: Command failed for target `t'babyblues:140 ls -l t-rw-rw-r-- 1 yip 24576 Jan 29 12:46 tbabyblues:141 make`t' is up to date.babyblues:142 Work around:Remove the target file. Bug End: Bug Id: 1041946 Product: sunos Category: compiler Subcategory: linker Release summary: 1.0, 4.0.3 Bug/Rfe: bug State: dispatched Synopsis: Small shared library with static external variables segmentation faults Keywords: faults, segmentati, external, static, library, shared Severity: 3 Priority: 3 Responsible Manager: gingell Description:It works if static is removed from: static int lucky_number;--------------------------- begin file "foo.c" -----------------------------static int lucky_number;int get_lucky_number(){ return(lucky_number);}void set_lucky_number(n) int n;{ lucky_number = n;}----------------------------- end file "foo.c" --------------------------------------------------------- begin file "foo.h" ------------------------------extern int get_lucky_number();extern void set_lucky_number();----------------------------- end file "foo.h" --------------------------------------------------------- begin file "baz.c" ------------------------------#include "foo.h"char buff[128];main(){ int n; printf("What is your lucky number? "); gets(buff); sscanf(buff, "%d", &n); set_lucky_number(n); printf("Feeling lucky yet ? "); /* pause for multi process testing */ gets(buff); printf("Your lucky number is %d\n", get_lucky_number());}----------------------------- end file "baz.c" --------------------------------------------------------- begin file "Makefile" ---------------------------CFLAGS =V = 0.0all: baz # static_bazfoo.o: foo.c cc $(CFLAGS) -c -pic foo.clibfoo.so.$(V): foo.o ld -o $@ -assert pure-text foo.obaz.o: baz.c cc $(CFLAGS) -c baz.cbaz: baz.o libfoo.so.$(V) Makefile cc -o $@ $(CFLAGS) -L. baz.o -lfoostatic_baz: baz.o foo.o cc -o $@ $(CFLAGS) baz.o foo.o -Bstaticclean: rm -f *.o baz *.so.* *~ core----------------------------- end file "Makefile" --------------------------- - WADEJ 15:26 28-Jun-90 -wadej 45: makecc -c baz.ccc -c -pic foo.cld -o libfoo.so.0.0 -assert pure-text foo.occ -o baz -L. baz.o -lfoowadej 46: lsMakefile baz.c foo.c foo.obaz baz.o foo.h libfoo.so.0.0wadej 47: bazWhat is your lucky number? 3Segmentationfault (core dumped)wadej 48:The description field as copied from bug report 1044969 follows:When an initialized static variable is in a C source program, and the program is compiled PIC, the linker, ld, is generating an incorrect relocation if the static variable is initialized in the source code rather than programmatically. To illustrate the effect, compile the following file as pic code:static int static_k = 20;int get_static_k(){ return(static_k);}Now, run ld over the compiled .o file to create a .so as follows: ld -o <file>.so <file>.oNow write a main program which uses dlopen() and dlsym() to dynamicallylink the file, look up the symbol _get_static_k, call the result as afunction, and print the result. Here is some code which does this:#include <stdio.h>#include <dlfcn.h>typedef int (*int_fn)();main(argc,argv) int argc; char** argv;{ void* handle; void* sym; int ret; if( --argc <= 0) { fprintf(stderr,"dyltest:Need at least 2 arguments.\n"); exit(1); } handle = dlopen((++argv)[0],1); while(*(++argv) != 0) { sym = dlsym(handle,*argv); printf("Found symbol %s:\n",*argv); printf("Executing as function...\n"); ret = (*(int_fn)sym)(); printf("Result:%d\n\n",ret); } exit(0);}You will find that the return value is 32, not 20. Note that if you programmatically initialize the static variable, it works correctly.If you follow through the dynamic linking and invocation, you will find that the static linker ld has generated a SPARC_32 relocation in the dynamic relocation table for the static variable static_k. The code which accesses static_k in the function assumes what is there is a pointer to where the value is, rather than the value itself. When the relocation is done, a random address is put into static_k. This address consists of the base address of the dynamically linked file in memory and the bits for the actual value of static_k. When the code in the function goes to get the value of static_k, it gets, instead, whatever is at the bogus address. Result: a random value.This effect goes away if the value 20 is *assigned* to static_k first, then read. Work around:From gingell@speed.Eng Fri Jul 13 11:33:51 1990The customer is seeing some sort of bug that causes simple .so's withonly a few static variables to have a misconstructed GOT. You can filea bug report, though it's highly unlikely that it will get fixed before"5.0", where it is already fixed.It's unlikely that most people building .so's will encounter this bug, becausemost .so's are more complex than this and aren't exposed to the problem.The workaround for this person would be to add a global variable that isunlikely to pollute any name space, and to reference that variable. Forinstance: int __foo_c_dummy; static int lucky_number; get_lucky_number() { return (__foo_c_dummy = lucky_number); } ... Bug End: Bug Id: 1050594 Product: sunos Category: compiler Subcategory: linker Release summary: 4.1 Bug/Rfe: bug State: dispatched Synopsis: Uninitialized struct slot causes intermittent failures Keywords: failures, intermitte, slot, struct, uninitiali Severity: 3 Priority: 3 Responsible Manager: gingell Description:In the source file ld.c in subroutine getlibname(),around line 1120, mymalloc() used to build a struct ldlibnode, but that node's ll_flag and ll_type fields are notinitialized. For small runs of ld, this doesn't matter,because the bits start out as zero, but if some other linkermodule does a "free", those bits might be garbage.Certain large runs of ld produce seemingly inexplicable errormessages, often "can't open foo.sa" or some anomaly accessingan archive member at the wrong access. This is often causedby these garbage flag values. Work around:The work around has been to rearrange the command lines of affected linkruns, until the problem seems to go away. Suggested fix:The fix is simple. Initialize the ll_flag and ll_type fieldsof the all newly-allocated struct ldlib nodes to 0. (Or initializethe ll_type flag to the variable "kind"; I don't care.) Bug End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -