On May 7, 2007, at 6:04 AM, Simon Marlow wrote:
Deborah Goldsmith wrote:

I believe what's going on here is that strerror has been changed for better Unix conformance, under the control of the __DARWIN_UNIX03 preprocessor flag. This is something you'll see in 10.4.x too. Here's an excerpt from /usr/include/unistd.h on 10.4.9:
#if __DARWIN_UNIX03
pid_t    setpgrp(void) __DARWIN_ALIAS(setpgrp);
#else /* !__DARWIN_UNIX03 */
int setpgrp(pid_t pid, pid_t pgrp); /* obsoleted by setpgid() */
#endif /* __DARWIN_UNIX03 */
where __DARWIN_ALIAS and __DARWIN_UNIX03 come from /usr/include/ sys/cdefs.h:
#if __DARWIN_UNIX03 && !defined(__LP64__)
#define __DARWIN_ALIAS(sym) __asm("_" __STRING(sym) "$UNIX2003")
#else
#define __DARWIN_ALIAS(sym)
#endif
The idea behind this is that if something is compiled with __DARWIN_UNIX03 (for Unix 2003 conformance) it links to a version of the routine with $UNIX2003 appended (for 32-bit architectures). If not, it gets the old version (for compatibility). In 10.5, strerror() now falls under this switch where it didn't in 10.4:
char    *strerror(int) __DARWIN_ALIAS(strerror);
(In this case the function signature hasn't changed as it did with setpgrp, but presumably the semantics have.)

I don't have a MacOS X machine here to investigate, but I can take a guess at what the problem is. When GHC compiles using its built- in native code generator, the names of functions mentioned in FFI declarations are taken literally: nothing is reading /usr/include/ unistd.h, so there's no way to make the connection between strerror and strerror$UNIX2003. To justify this, we say that the Haskell FFI is binding to the C ABI, not API.

The way to work around it is to add a stub C function to one of the C files in the base package, e.g. HsBase.h. There are many such stubs there already, for C functions that are implemented as macros. In most cases the C standard says which functions are allowed to be implemented as macros, so we can use appropriate stubs to forestall such issues, but changing the name with __asm doesn't count as a macro (presumably that's why you guys did it this way?).

Thanks for replying!

Actually, I'm not sure that's what's going on. The unresolved symbol error is:

../../compiler/ghc-inplace -H16m -O -fglasgow-exts -cpp -Iinclude -"#include" HsBase.h -funbox-strict-fields -package-name base-2.1.1 -O -Rghc-timing -fgenerics -fgenerics -split-objs -c Foreign/C/Error.hs -o Foreign/C/Error.o -ohi Foreign/C/Error.hi /tmp/ghc78351_0/ghc78351_0.split__108.s:unknown:Undefined local symbol L_strerror$UNIX2003$stub

So the reference actually is to the version *with* $UNIX2003 appended. Also, both strerror and strerror$UNIX2003 are present in the library being linked against, so if the FFI were going straight to strerror (old version), it would find it, because it's still there for compatibility.

The only way that a symbol like L_strerror$UNIX2003$stub would be generated would be if someone *were* including unistd.h. There's no way the $UNIX2003 would creep in otherwise. Also, it says it's a "local symbol." Also note the leading L; I would expect the symbol to be _strerror$UNIX2003$stub. The actual symbols exported by /usr/lib/ libSystem.dylib in 10.5 are:

0000c59c T _strerror
000b7fb4 T _strerror$UNIX2003

Thanks again,
Deborah

_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to