[NetBSD-PR lib/46163] netbsd-6 build broken at tests/lib/libobjc

Issue #102 resolved
Takehiko NOZAKI repo owner created an issue

see detail: http://gnats.netbsd.org/cgi-bin/query-pr-single.pl?number=46163

if libobjc is built with -g(=debug) option + -stdc={c99,gnu99} some inline function(objc_read_* etc) become missing undefined symbol.

  1. gcc always erase inline function body.
  2. but gcc don't expand inline function into caller.
  3. so inline function become undefined symbol

Comments (6)

  1. Takehiko NOZAKI reporter

    minimal case is:

    $ cat>test.c
    #include <stdio.h>
    
    extern void bar(void);
    
    inline int
    foo()
    {
            printf("foo\n");
    }
    
    int
    bar()
    {
            foo();
            printf("bar\n");
    }
    ^D
    

    compile and check symbol:

    $ gcc -shared -fPIC -std=c99 -O2 a.c -o a.o
    nm a.o | grep foo
    

    if -O2 is specified, foo() is expaned as inline.

    $ gcc -shared -fPIC -std=c99 -g a.c -o a.o
    $ nm a.o | grep foo
                     U foo
    

    but if -g is specified, foo() is not expaned so it become undefined symbol.

  2. Takehiko NOZAKI reporter
    $ gcc --version
    gcc (NetBSD nb2 20110806) 4.5.3
    Copyright (C) 2010 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
  3. Takehiko NOZAKI reporter

    ISO/IEC9899:1999 says that if you want export the symbol and exand inline same time, decrate following prototype:

    extern void foo(void);
    
    inline void
    foo()
    {
        ...
    }
    

    or if you want only expand inline function, use static inline:

    static inline void
    foo()
    {
        ...
    }
    

    but libobjc's code don't have extern prototype or static inline decls. it is bad behavior.

  4. Takehiko NOZAKI reporter

    i believe following function in archive.c is not public API because these were not defined in objc.h.

    __objc_read_nbyte_uint
    __objc_read_nbyte_ulong
    __objc_write_class
    __objc_write_object
    __objc_write_selector
    objc_read_char
    objc_read_int
    objc_read_long
    objc_read_selector
    objc_read_short
    objc_read_string
    objc_read_unsigned_char
    objc_read_unsigned_int
    objc_read_unsigned_long
    objc_read_unsigned_short
    objc_write_char
    objc_write_int
    objc_write_long
    objc_write_selector
    objc_write_short
    objc_write_string
    objc_write_string_atomic
    objc_write_unsigned_char
    objc_write_unsigned_int
    objc_write_unsigned_long
    objc_write_unsigned_short
    

    so that simply change inline -> static inline.

    following function in sendmsg.c too.

    __objc_get_forward_imp
    

    be aware, recent gcc applied following patch:

    https://patchwork.ozlabs.org/patch/433574/

    they revive __objc_get_forward_imp symbol. but i don't think it is not nessesary expect get_imp() ABI.

  5. Log in to comment