Article View: gnu.gcc.bug
Article #6300Kernel symbol import list bug in gcc-2.7.2's ld on AIX 4.1.3.0
From: Alain Knaff
Date: Tue, 12 Dec 1995 00:00
Date: Tue, 12 Dec 1995 00:00
105 lines
4347 bytes
4347 bytes
In gcc version 2.7.2 running on an Estrella Powerpc with Aix 4.1.3.0
Gcc seems to have a problem whith compiling kernel modules which
import symbol lists.
Here is a small example to reproduce the problem:
example.exp:
#!/unix
pincode
example.c:
int test(void)
{
pincode(test);
}
When compiling this with the following command line I get an error message:
gcc -nostdlib -Wl,-e -Wl,test -Wl,-bimport:./example.exp example.c -lsys -lcs
ys
collect2: /: library not found
#!/unix (in example.exp) means that the .exp file contains symbols
exported by the kernel, no user mode shared library is involved. This
line is used in most kernel export files: /lib/kernex.exp,
/lib/aio.exp, /lib/pcmciacs.exp, /lib/rcm.exp, /lib/sockets.exp,
/lib/statcmd.exp, /lib/syscalls.exp, /lib/threads.exp and /lib/vme.exp
.
Apparently gcc doesn't know this fact, and assumes that the name
after #! is always a library which exists in filespace and can be
read.
Gcc-2.6.3 used to grok those just fine and produced working kernel
modules. The problem seems to stem from gcc's ld: If I place the old
ld from 2.6.3 in gcc-2.7.2's tree, it works.
Here is the relevant code snippet in collect2.c where the message is
generated.
2621 while (idx < ldh.l_istlen)
2622 {
2623 char *implib = impbuf + idx;
2624 char *impmem = implib + strlen (implib) + 1;
2625 char *soname = 0;
2626 LDFILE *libptr = NULL;
2627 struct prefix_list *pl;
2628 ARCHDR ah;
2629 idx += strlen (implib) + 1;
2630 if (!implib[0])
2631 continue;
2632 idx += strlen (impmem) + 1;
2633 if (*implib == '/')
2634 {
2635 if (access (soname, R_OK) == 0)
2636 soname = implib;
2637 }
2638 else
2639 {
2640 char *temp = alloca (libpath.max_len + strlen (implib) + 1
);
2641 for (pl = libpath.plist; pl; pl = pl->next)
2642 {
2643 strcpy (temp, pl->prefix);
2644 strcat (temp, implib);
2645 if (access (temp, R_OK) == 0)
2646 {
2647 soname = temp;
2648 break;
2649 }
2650 }
2651 }
2652 if (!soname)
2653 {
2654 fatal ("%s: library not found", implib);
2655 continue;
2656 }
This doesn't seem quite right to me. Indeed, initially (at line
2625), soname is set to 0. If implib begins with a slash (which is the
case here), it tests the existance of the file named soname. This
happens at line 2635. At this point, soname is still a NULL pointer!
If the file exists, soname because implib (line 2636). However, this
branch is never taken, as adress 0 probably just contains random
characters denoting a non-existant file :-) Thus soname will stay 0.
Execution then continues at line 2652 where the error message is
generated.
The intent was probably to find out whether implib was readable, and
not soname.
However, after changing line 2635 from 'if (access (soname, R_OK) ==
0)' to 'if (access (implib, R_OK) == 0)' the error message becomes:
collect2: /: not an import library
After changing line 2630 from if (!implib[0]) to if (!implib[0] ||
(implib[0]=='/' && !implib[1])), the message becomes:
collect2: unix: library not found
Obviously, there's no easy way to convince ld that /unix is not a
library existing in filespace but rather the kernel. At this point I
gave up and went back to 2.6.3's ld.
Alain
Technical Details
Message-ID:
<199512121436.PAA02361@ngulu.imag.fr.imag.fr>Path:
arc1-ca.pugleaf.net!unknown!not-for-mailShow Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 113d02,b99fcee951c506f0,start X-Google-Attributes: gid113d02,public From: Alain.Knaff@imag.fr (Alain Knaff) Subject: Kernel symbol import list bug in gcc-2.7.2's ld on AIX 4.1.3.0 Date: 1995/12/12 Message-ID: <199512121436.PAA02361@ngulu.imag.fr.imag.fr> X-Deja-AN: 121609974 distribution: gnu sender: daemon@cis.ohio-state.edu organization: GNUs Not Usenet reply-to: Alain.Knaff@imag.fr newsgroups: gnu.gcc.bug