tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Reducing ld.elf_so relocations and size



Hi all,
attached patch in combination with the environment handling patch I send
earlier addresses two issues with ld.elf_so:

(1) It has too many runtime relocations because the integrated libc
doesn't exploit the fact that the non-local references are still hidden.
E.g. on AMD64, both data access and function calls can be done relative
to the instruction pointer without using the GOT. This improves code
size and startup time. The changes around errlist reduce the number of
runtime relocations for one for every errno value and give around 3KB on
AMD64.

(2) It (almost) allows to drop the special visibility hacks in
ld.elf_so. Look at the output of 'readelf -s ld.elf_so' and the long
list of GLOBAL symbols with DEFAULT visiblity. After the patch, only 3
symbols are still visible that shouldn't be (__bss_start, _edata, _end)
and they come from the ld script used. It should be fixed to make them
hidden or protected, but that's a separate discussion.

The patch is currently missing the !x86 machine/asm.h changes and some
other minor changes to avoid some GOT references. Some platforms might
need additional helper code as well, but that's easy to identify.

The patch also doesn't contain a build time assertion for the symbol
list of ld.elf_so yet.

There are some further changes to consider like making __cerror a hidden
lymbol, taking it out of the public namespace. It would allow taking the
shorter code sequence for the shared library build as well.

I know that the global define trick is not the most beautiful approach,
but I haven't found an idea that involves less code changes and still
gives the benefits of (1). More importantly, I would strongly prefer to
only have to source code as optimisation, not to make it work. I also
don't want to duplicate the logic from libc to decide where a specific
source file lives and if the C version or the MD assembler should be
used. Ideas are welcome.

Joerg
Index: include/dlfcn.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/dlfcn.h,v
retrieving revision 1.21
diff -u -p -r1.21 dlfcn.h
--- include/dlfcn.h     7 Jan 2010 07:35:35 -0000       1.21
+++ include/dlfcn.h     5 Dec 2010 04:00:23 -0000
@@ -47,7 +47,7 @@ typedef struct _dl_info {
 /*
  * User interface to the run-time linker.
  */
-__BEGIN_DECLS
+__BEGIN_PUBLIC
 void   *dlopen(const char *, int);
 int    dlclose(void *);
 void   *dlsym(void * __restrict, const char * __restrict);
@@ -57,7 +57,7 @@ int   dlctl(void *, int, void *);
 int    dlinfo(void *, int, void *);
 #endif
 __aconst char *dlerror(void);
-__END_DECLS
+__END_PUBLIC
 
 /* Values for dlopen `mode'. */
 #define RTLD_LAZY      1
Index: include/link_elf.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/include/link_elf.h,v
retrieving revision 1.10
diff -u -p -r1.10 link_elf.h
--- include/link_elf.h  16 Oct 2010 10:27:06 -0000      1.10
+++ include/link_elf.h  5 Dec 2010 03:59:35 -0000
@@ -43,11 +43,11 @@ struct dl_phdr_info
        void *dlpi_tls_data;
 };
 
-__BEGIN_DECLS
+__BEGIN_PUBLIC
 
 int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
     void *);
 
-__END_DECLS
+__END_PUBLIC
 
 #endif /* _LINK_ELF_H_ */
Index: lib/libc/Makefile
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/Makefile,v
retrieving revision 1.143
diff -u -p -r1.143 Makefile
--- lib/libc/Makefile   4 Sep 2010 12:17:58 -0000       1.143
+++ lib/libc/Makefile   10 Dec 2010 00:54:54 -0000
@@ -118,6 +118,50 @@ LSRCS := ${LSRCS} ${unwanted_file}
 .endif
 .endfor
 
+.SUFFIXES: .hpico
+
+errlist_concat.c: errlist.c
+       ${_MKTARGET_CREATE}
+       ${TOOL_AWK} -f ${LIBCDIR}/gen/errlist.awk < ${.ALLSRC} \
+           > errlist_concat.c.tmp && \
+       mv -f errlist_concat.c.tmp errlist_concat.c
+
+CLEANFILES+=   errlist_concat.c
+
+.c.hpico:
+       ${_MKTARGET_COMPILE}
+       ${COMPILE.c} ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} 
${CPPFLAGS.${.IMPSRC:T}} ${CSHLIBFLAGS} -fvisibility=hidden -U_REENTRANT 
-D__FORCE_HIDDEN_DEFAULT ${.IMPSRC} -o ${.TARGET}
+.if !defined(CFLAGS) || empty(CFLAGS:M*-g*)
+       ${OBJCOPY} -x ${.TARGET}
+.endif
+
+.s.hpico:
+       ${_MKTARGET_COMPILE}
+       ${COMPILE.s} ${CAPICFLAGS} ${COPTS.${.IMPSRC:T}} 
${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} -U_REENTRANT 
-D__FORCE_HIDDEN_DEFAULT ${.IMPSRC} -o ${.TARGET}
+       ${OBJCOPY} -x ${.TARGET}
+
+.S.hpico:
+       ${_MKTARGET_COMPILE}
+       ${COMPILE.S} ${CAPICFLAGS} ${COPTS.${.IMPSRC:T}} 
${CPUFLAGS.${.IMPSRC:T}} ${CPPFLAGS.${.IMPSRC:T}} -U_REENTRANT 
-D__FORCE_HIDDEN_DEFAULT ${.IMPSRC} -o ${.TARGET}
+       ${OBJCOPY} -x ${.TARGET}
+
+realall: libc_hidden.a
+
+# Functions called by ld.elf_so and the transitive closure
+HIDDEN_SRCS+=  __fstat50 __sigaction_sigtramp __sigaction14_sigtramp \
+               __sigtramp2 __sigprocmask14 __sysctl _errno _exit \
+               _lwp_kill _lwp_self \
+               abort cerror close ctype_ errlist_concat errno geteuid \
+               getuid getegid getgid getprogname \
+               memcpy memcpy_chk memset mmap mprotect munmap open raise \
+               read signal strchr strcmp strcpy strlcpy strlen \
+               strncmp strncpy strrchr strsep sysctl tmp_mmap write
+# Helper functions for 64bit division on some platforms.
+HIDDEN_SRCS+=  qdivrem udivdi3
+HIDDEN_OBJS+=  ${HIDDEN_SRCS:C,$,.hpico,}
+
+libc_hidden.a:: ${HIDDEN_OBJS} __archivebuild
+
 NLS=   C.msg Pig.msg ca.msg cs.msg de.msg es.msg fi.msg fr.msg nl.msg \
        no.msg pl.msg sk.msg sv.msg
 
Index: lib/libc/arch/i386/SYS.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/arch/i386/SYS.h,v
retrieving revision 1.23
diff -u -p -r1.23 SYS.h
--- lib/libc/arch/i386/SYS.h    28 Apr 2008 20:22:56 -0000      1.23
+++ lib/libc/arch/i386/SYS.h    9 Dec 2010 22:20:10 -0000
@@ -101,7 +101,7 @@
        ENTRY(x);                                                       \
        SYSTRAP(y)
 
-#ifdef PIC
+#if defined(PIC) && !defined(__FORCE_HIDDEN_DEFAULT)
 #define _SYSCALL_ERR                                                   \
        PIC_PROLOGUE;                                                   \
        mov PIC_GOT(CERROR), %ecx;                                      \
Index: lib/libc/arch/i386/sys/cerror.S
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/arch/i386/sys/cerror.S,v
retrieving revision 1.14
diff -u -p -r1.14 cerror.S
--- lib/libc/arch/i386/sys/cerror.S     7 Aug 2003 16:42:08 -0000       1.14
+++ lib/libc/arch/i386/sys/cerror.S     9 Dec 2010 22:21:23 -0000
@@ -45,7 +45,7 @@
 
 _ENTRY(CERROR)
        pushl   %eax
-#ifdef PIC
+#if defined(PIC) && !defined(__FORCE_HIDDEN_DEFAULT)
        PIC_PROLOGUE
        call    PIC_PLT(_C_LABEL(__errno))
        PIC_EPILOGUE
Index: lib/libc/arch/x86_64/SYS.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/arch/x86_64/SYS.h,v
retrieving revision 1.10
diff -u -p -r1.10 SYS.h
--- lib/libc/arch/x86_64/SYS.h  23 Nov 2007 07:36:05 -0000      1.10
+++ lib/libc/arch/x86_64/SYS.h  9 Dec 2010 03:12:16 -0000
@@ -49,7 +49,7 @@
        ENTRY(x);                                                       \
        SYSTRAP(y)
 
-#ifdef PIC
+#if defined(PIC) && !defined(__FORCE_HIDDEN_DEFAULT)
 #define _SYSCALL_ERR                                                   \
        mov PIC_GOT(CERROR), %rcx;                                      \
        jmp *%rcx
Index: lib/libc/arch/x86_64/sys/cerror.S
===================================================================
RCS file: /home/joerg/repo/netbsd/src/lib/libc/arch/x86_64/sys/cerror.S,v
retrieving revision 1.3
diff -u -p -r1.3 cerror.S
--- lib/libc/arch/x86_64/sys/cerror.S   7 Aug 2003 16:42:37 -0000       1.3
+++ lib/libc/arch/x86_64/sys/cerror.S   9 Dec 2010 02:56:56 -0000
@@ -42,12 +42,15 @@
 #include "SYS.h"
 
        .globl  _C_LABEL(__errno)
+#if defined(__FORCE_HIDDEN_DEFAULT)
+       .hidden _C_LABEL(__errno)
+#endif
 
 _ENTRY(CERROR)
        pushq   %r12
        movl    %eax,%edi
        movl    %eax,%r12d
-#ifdef PIC
+#if defined(PIC) && !defined(__FORCE_HIDDEN_DEFAULT)
        call    PIC_PLT(_C_LABEL(__errno))
 #else
        call    _C_LABEL(__errno)
Index: lib/libc/gen/errlist.awk
===================================================================
RCS file: lib/libc/gen/errlist.awk
diff -N lib/libc/gen/errlist.awk
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ lib/libc/gen/errlist.awk    9 Dec 2010 04:19:54 -0000
@@ -0,0 +1,23 @@
+BEGIN {
+       offset = 0
+       i = 0
+       print "const char concat_errlist[] = {"
+}
+
+/EL\(\(".*"\)\)/       {
+       offsets[i++] = offset
+       match($0, /EL\(\(".*"\)\)/)
+       printf "\t%s \"\\0\"\n", substr($0, RSTART + 4, RLENGTH - 6)
+       offset = offset + RLENGTH - 8 + 1
+}
+END {
+       print "};"
+       print "const int concat_nerr = " i ";"
+       print "const unsigned short concat_offset[" (i + 1) "] = {"
+       offsets[i++] = offset
+       for (j = 0; j < i; j++) {
+               printf "\t%d,\n", offsets[j]
+       }
+       print "};"
+       if (offset > 65535) exit(1)
+}
Index: libexec/ld.elf_so/Makefile
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/Makefile,v
retrieving revision 1.99
diff -u -p -r1.99 Makefile
--- libexec/ld.elf_so/Makefile  5 Dec 2010 00:56:06 -0000       1.99
+++ libexec/ld.elf_so/Makefile  5 Dec 2010 03:58:12 -0000
@@ -1,4 +1,4 @@
-#      $NetBSD: src/libexec/ld.elf_so/Makefile,v 1.99 2010-12-05 00:56:06 
joerg Exp $
+#      $NetBSD: Makefile,v 1.99 2010/12/05 00:56:06 joerg Exp $
 #
 # NOTE: when changing ld.so, ensure that ldd still compiles.
 #
@@ -38,9 +38,10 @@ M=           ${.CURDIR}/arch/${ARCHSUBDIR}
      (${MACHINE_ARCH} == "vax")) &&                                    \
     ${MKPIC} != "no"
 
-LDFLAGS+=      -shared -symbolic -nostartfiles
+LDFLAGS+=      -shared -symbolic -nostdlib -nostartfiles
 LDFLAGS+=      -Wl,-static
 CFLAGS+=       -fvisibility=hidden
+CPPFLAGS+=     -D__FORCE_HIDDEN_DEFAULT
 
 # Adds SRCS, CPPFLAGS, LDFLAGS, etc.  Must go first so MD startup source
 # is first.
@@ -58,7 +59,7 @@ PROG=         ld.elf_so
 
 CLIBOBJ!=      cd ${NETBSDSRCDIR}/lib/libc && ${PRINTOBJDIR}
 
-SRCS+=         rtld.c reloc.c symbol.c xenv.c xmalloc.c xprintf.c debug.c \
+SRCS+=         rtld.c reloc.c symbol.c xmalloc.c xprintf.c debug.c \
                map_object.c load.c search.c headers.c paths.c expand.c
 
 .if ${USE_FORT} == "yes"
@@ -90,16 +91,17 @@ CPPFLAGS+=  -DRTLD_DEFAULT_LIBRARY_PATH=\
 COPTS.rtld.c+= -Wno-stack-protector
 COPTS.symbol.c+=-Wno-stack-protector
 
-LDADD+=                -L${CLIBOBJ} -L${DESTDIR}${LIBDIR}
+LDADD+=                -L${CLIBOBJ} -L${DESTDIR}${LIBDIR} -lc_hidden 
-Wl,-z,defs
+DPADD+=                ${CLIBOBJ}/libc_hidden.a
 .if ${MKPICLIB} != "no"
-LDADD+=                -lc_pic
+#LDADD+=               -lc_pic
 .if ${MKPICINSTALL} != "no"
-DPADD+=                ${LIBC_PIC}
+#DPADD+=               ${LIBC_PIC}
 .endif
-DPADD+=                ${CLIBOBJ}/libc_pic.a
+#DPADD+=               ${CLIBOBJ}/libc_pic.a
 .else
-LDADD+=                -lc
-DPADD+=                ${CLIBOBJ}/libc.a
+#LDADD+=               -lc
+#DPADD+=               ${CLIBOBJ}/libc.a
 .endif
 
 STRIPFLAG=
Index: libexec/ld.elf_so/xprintf.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/xprintf.c,v
retrieving revision 1.20
diff -u -p -r1.20 xprintf.c
--- libexec/ld.elf_so/xprintf.c 19 May 2009 20:44:52 -0000      1.20
+++ libexec/ld.elf_so/xprintf.c 9 Dec 2010 04:26:54 -0000
@@ -243,16 +243,20 @@ xsnprintf(char *buf, size_t buflen, cons
        va_end(ap);
 }
 
+extern const char concat_errlist[];
+extern const int concat_nerr;
+extern const unsigned short concat_offset[];
+
 const char *
 xstrerror(int error)
 {
 
-       if (error >= sys_nerr || error < 0) {
+       if (error >= concat_nerr || error < 0) {
                static char buf[128];
                xsnprintf(buf, sizeof(buf), "Unknown error: %d", error);
                return buf;
        }
-       return sys_errlist[error];
+       return concat_errlist + concat_offset[error];
 }
 
 void
Index: sys/arch/amd64/include/asm.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/arch/amd64/include/asm.h,v
retrieving revision 1.13
diff -u -p -r1.13 asm.h
--- sys/arch/amd64/include/asm.h        26 Oct 2008 00:08:15 -0000      1.13
+++ sys/arch/amd64/include/asm.h        9 Dec 2010 04:29:47 -0000
@@ -69,8 +69,14 @@
 # endif
 #endif
 
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define _ENTRY(x) \
+       .text; _ALIGN_TEXT; .globl x; .hidden x; .type x,@function; x:
+#else
 #define _ENTRY(x) \
        .text; _ALIGN_TEXT; .globl x; .type x,@function; x:
+#endif
+
 #define _LABEL(x) \
        .globl x; x:
 
@@ -108,16 +114,30 @@
 
 #define RCSID(x)       .pushsection ".ident"; .asciz x; .popsection
 
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define        WEAK_ALIAS(alias,sym)                                           
\
+       .weak alias;                                                    \
+       .hidden alias;                                                  \
+       alias = sym
+#else
 #define        WEAK_ALIAS(alias,sym)                                           
\
        .weak alias;                                                    \
        alias = sym
+#endif
 
 /*
  * STRONG_ALIAS: create a strong alias.
  */
+#if defined(__FORCE_HIDDEN_DEFAULT)
 #define STRONG_ALIAS(alias,sym)                                                
\
+       .hidden alias;                                                  \
        .globl alias;                                                   \
        alias = sym
+#else
+#define STRONG_ALIAS(alias,sym)                                                
\
+       .globl alias;                                                   \
+       alias = sym
+#endif
 
 /* XXXfvdl do not use stabs here */
 #ifdef __STDC__
Index: sys/arch/i386/include/asm.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/arch/i386/include/asm.h,v
retrieving revision 1.38
diff -u -p -r1.38 asm.h
--- sys/arch/i386/include/asm.h 3 May 2008 05:54:52 -0000       1.38
+++ sys/arch/i386/include/asm.h 9 Dec 2010 22:23:53 -0000
@@ -93,8 +93,13 @@
 # endif
 #endif
 
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define _ENTRY(x) \
+       .text; _ALIGN_TEXT; .globl x; .hidden x; .type x,@function; x:
+#else
 #define _ENTRY(x) \
        .text; _ALIGN_TEXT; .globl x; .type x,@function; x:
+#endif
 #define _LABEL(x) \
        .globl x; x:
 
@@ -192,16 +197,30 @@
 #endif
 
 #ifdef __ELF__
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define        WEAK_ALIAS(alias,sym)                                           
\
+       .weak alias;                                                    \
+       .hidden alias;                                                  \
+       alias = sym
+#else
 #define        WEAK_ALIAS(alias,sym)                                           
\
        .weak alias;                                                    \
        alias = sym
 #endif
+#endif
 /*
  * STRONG_ALIAS: create a strong alias.
  */
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define STRONG_ALIAS(alias,sym)                                                
\
+       .hidden alias;                                                  \
+       .globl alias;                                                   \
+       alias = sym
+#else
 #define STRONG_ALIAS(alias,sym)                                                
\
        .globl alias;                                                   \
        alias = sym
+#endif
 
 #ifdef __STDC__
 #define        WARN_REFERENCES(sym,msg)                                        
\
Index: sys/sys/cdefs.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/sys/cdefs.h,v
retrieving revision 1.80
diff -u -p -r1.80 cdefs.h
--- sys/sys/cdefs.h     7 Aug 2010 21:03:18 -0000       1.80
+++ sys/sys/cdefs.h     9 Dec 2010 04:11:54 -0000
@@ -218,31 +218,39 @@
 #define        __used          __unused
 #endif
 
+#if defined(__cplusplus)
+#  define __BEGIN_EXTERN_C     extern "C" {
+#  define __END_EXTERN_C       }
+#  define __static_cast(x,y)   static_cast<x>(y)
+#else
+#  define __BEGIN_EXTERN_C
+#  define __END_EXTERN_C
+#  define __static_cast(x,y)   (x)y
+#endif
+
 #if __GNUC_PREREQ__(4, 0)
 #  define __dso_public __attribute__((__visibility__("default")))
 #  define __dso_hidden __attribute__((__visibility__("hidden")))
-#  define __BEGIN_PUBLIC       _Pragma("GCC visibility push(default)")
-#  define __END_PUBLIC         _Pragma("GCC visibility pop")
-#  define __BEGIN_HIDDEN       _Pragma("GCC visibility push(hidden)")
-#  define __END_HIDDEN         _Pragma("GCC visibility pop")
+#  define __BEGIN_PUBLIC       _Pragma("GCC visibility push(default)") 
__BEGIN_EXTERN_C
+#  define __END_PUBLIC         __END_EXTERN_C _Pragma("GCC visibility pop")
+#  define __BEGIN_HIDDEN       _Pragma("GCC visibility push(hidden)") 
__BEGIN_EXTERN_C
+#  define __END_HIDDEN         __END_EXTERN_C _Pragma("GCC visibility pop")
 #else
 #  define __dso_public
 #  define __dso_hidden
-#  define __BEGIN_PUBLIC
-#  define __END_PUBLIC
-#  define __BEGIN_HIDDEN
-#  define __END_HIDDEN
+#  define __BEGIN_PUBLIC       __BEGIN_EXTERN_C
+#  define __END_PUBLIC         __END_EXTERN_C
+#  define __BEGIN_HIDDEN       __BEGIN_EXTERN_C
+#  define __END_HIDDEN         __END_EXTERN_C
 #endif
 
 
-#if defined(__cplusplus)
-#define        __BEGIN_DECLS           __BEGIN_PUBLIC extern "C" {
-#define        __END_DECLS             } __END_PUBLIC
-#define        __static_cast(x,y)      static_cast<x>(y)
-#else
-#define        __BEGIN_DECLS           __BEGIN_PUBLIC
-#define        __END_DECLS             __END_PUBLIC
-#define        __static_cast(x,y)      (x)y
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define        __BEGIN_DECLS   __BEGIN_HIDDEN
+#define        __END_DECLS     __END_HIDDEN
+#else
+#define        __BEGIN_DECLS   __BEGIN_PUBLIC
+#define        __END_DECLS     __END_PUBLIC
 #endif
 
 /*
Index: sys/sys/cdefs_elf.h
===================================================================
RCS file: /home/joerg/repo/netbsd/src/sys/sys/cdefs_elf.h,v
retrieving revision 1.34
diff -u -p -r1.34 cdefs_elf.h
--- sys/sys/cdefs_elf.h 8 Dec 2010 01:18:55 -0000       1.34
+++ sys/sys/cdefs_elf.h 9 Dec 2010 02:55:07 -0000
@@ -51,13 +51,22 @@
 
 #define        __indr_reference(sym,alias)     /* nada, since we do weak refs 
*/
 
+#if defined(__FORCE_HIDDEN_DEFAULT)
+#define        __hidden_alias_text(sym)        ".hidden " sym ";"
+#else
+#define        __hidden_alias_text(sym)
+#endif
+
+
 #if __STDC__
 #define        __strong_alias(alias,sym)                                       
\
-    __asm(".global " _C_LABEL_STRING(#alias) "\n"                      \
+    __asm(__hidden_alias_text(_C_LABEL_STRING(#alias)) \
+           ".global " _C_LABEL_STRING(#alias) "\n"                     \
            _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
 
 #define        __weak_alias(alias,sym)                                         
\
-    __asm(".weak " _C_LABEL_STRING(#alias) "\n"                        \
+    __asm(__hidden_alias_text(_C_LABEL_STRING(#alias)) \
+           ".weak " _C_LABEL_STRING(#alias) "\n"                       \
            _C_LABEL_STRING(#alias) " = " _C_LABEL_STRING(#sym));
 
 /* Do not use __weak_extern, use __weak_reference instead */
@@ -86,10 +95,10 @@
 #ifdef __LEADING_UNDERSCORE
 #define __weak_alias(alias,sym) ___weak_alias(_/**/alias,_/**/sym)
 #define        ___weak_alias(alias,sym)                                        
\
-    __asm(".weak alias\nalias = sym");
+    __asm(__hidden_alias_text(alias) ".weak alias\nalias = sym");
 #else
 #define        __weak_alias(alias,sym)                                         
\
-    __asm(".weak alias\nalias = sym");
+    __asm(__hidden_alias_text(alias) ".weak alias\nalias = sym");
 #endif
 #ifdef __LEADING_UNDERSCORE
 #define __weak_extern(sym) ___weak_extern(_/**/sym)


Home | Main Index | Thread Index | Old Index