[GHC] #12169: libraries/base/dist-install/build/HSbase-4.9.0.0.o: unknown symbol `stat'

GHC ghc-devs at haskell.org
Wed Jul 20 16:27:13 UTC 2016


#12169: libraries/base/dist-install/build/HSbase-4.9.0.0.o: unknown symbol `stat'
-------------------------------------+-------------------------------------
        Reporter:  thomie            |                Owner:
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Runtime System    |              Version:  8.0.1
  (Linker)                           |
      Resolution:                    |             Keywords:
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by rwbarton):

 https://www.redhat.com/archives/pam-list/1999-February/msg00082.html has
 the answer. Apparently little has changed in 17 years.

 What's happening is

 * `libc.so.6` defines only `__xstat`, not `stat`.

 * `sys/stat.h` defines `stat` as an extern inline function that calls
 `__xstat`. With optimizations enabled, gcc expands the inline function
 call to its definition, so it generates a reference to `__xstat` and
 that's that.

 * `libc.so` is a linker script that pulls in `libc.so.6` and
 `libc_nonshared.a`. The latter library contains the standalone definition
 of the function `stat` that a C program compiled without optimizations
 will be linked against.

 * If you link something with gcc then it will automatically link in `-lc`,
 because gcc is a C compiler. However if you link a shared library manually
 using `ld -shared` then ld will not add `-lc`, because ld is not a "C
 linker". This usually works okay in practice anyways, because you are
 linking or `dlopen()`ing the shared library into a C program. In the
 `dlopen()` case, the shared library can see the parts of the C library
 that are in `libc.so.6`, but not the parts that are in `libc_nonshared.a`.
 This is the problem in that email thread.

 In our case we use `ld -r` to combine all the object files for the `base`
 library into one `.o` file for faster loading into the RTS linker. I don't
 know whether there is an equivalent to `-lc` here that will also link in
 just the needed bits of `libc_nonshared.a`. Even the entirety of
 `libc_nonshared.a` is quite small (22K), but in my attempts I could only
 get ld to link against the entire static `libc.a`, which is unacceptable.

 One thing that would work is to load `libc_nonshared.a` into the RTS
 linker at startup time, but that's probably glibc-specific. Trying to
 parse the linker script `libc.so` sounds like a rabbit hole. As a hack, we
 could also just add `stat` and whatever else we need to `RtsSymbols.c`.
 (Or ideally, just deprecate the RTS linker...)

--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/12169#comment:2>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler


More information about the ghc-tickets mailing list