one function (in a library) - two (or more) names - Unix

This is a discussion on one function (in a library) - two (or more) names - Unix ; Is there a way to create functions in a library so that references can be made to that function using two different symbol names (e.g. an alias), where either of those names may have been used to produce the object ...

+ Reply to Thread
Results 1 to 10 of 10

Thread: one function (in a library) - two (or more) names

  1. one function (in a library) - two (or more) names

    Is there a way to create functions in a library so that references can be
    made to that function using two different symbol names (e.g. an alias),
    where either of those names may have been used to produce the object code
    making reference to the function?

    I know I can fake function aliases at compile time with macros. But I am
    asking about a way to do this so that it can be done at linking time.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-06-02-1225@ipal.net |
    |------------------------------------/-------------------------------------|

  2. Re: one function (in a library) - two (or more) names

    phil-news-nospam@ipal.net writes:

    > Is there a way to create functions in a library so that references can be
    > made to that function using two different symbol names (e.g. an alias),


    Yes, on some platforms.

    On Linux (and other ELF platforms with gcc-3.x), do this:

    void foo() { }
    void bar() __attribute__((alias("foo")));

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  3. Re: one function (in a library) - two (or more) names

    On Sat, 02 Jun 2007 11:30:54 -0700 Paul Pluzhnikov wrote:
    | phil-news-nospam@ipal.net writes:
    |
    |> Is there a way to create functions in a library so that references can be
    |> made to that function using two different symbol names (e.g. an alias),
    |
    | Yes, on some platforms.
    |
    | On Linux (and other ELF platforms with gcc-3.x), do this:
    |
    | void foo() { }
    | void bar() __attribute__((alias("foo")));

    Thanks. That looks like it might do what I want. Does bar() have to have
    exactly the same argument list as foo(), or just none will do (in the
    definition, not in the declaration found in whatever headers the program
    that is compiled to call bar() instead of foo() will see, which clearly
    must have the arguments).

    Is this form correct:

    void foo(double a,long b,int c) { }
    void bar() __attribute__((alias("foo")));

    Or is this form correct:

    void foo(double a,long b,int c) { }
    void bar(double a,long b,int c) __attribute__((alias("foo")));


    A program with this code:

    printf("%d\n",foo==bar);

    plus appropriate header declarations and then linked to a library with the
    above functions would print a non-zero value, I presume.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-06-02-1537@ipal.net |
    |------------------------------------/-------------------------------------|

  4. Re: one function (in a library) - two (or more) names

    phil-news-nospam@ipal.net writes:

    > Is this form correct:
    >
    > void foo(double a,long b,int c) { }
    > void bar() __attribute__((alias("foo")));
    >
    > Or is this form correct:
    >
    > void foo(double a,long b,int c) { }
    > void bar(double a,long b,int c) __attribute__((alias("foo")));


    Either form is accepted by gcc/g++ 3.3.3 and 4.2.0.
    The latter form is "more correct" than the former.
    [Also, in C++ "foo" must have 'extern "C"' linkage.]

    > A program with this code:
    >
    > printf("%d\n",foo==bar);
    >
    > plus appropriate header declarations and then linked to a library with the
    > above functions would print a non-zero value, I presume.


    This is generally non-portable, I believe.

    On Linux it does answer 1, but on platforms where function pointer
    is more than just a .text address (e.g. HP-UX/PA-RISC, AIX/PowerPC,
    */ia64) it may or may not.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  5. Re: one function (in a library) - two (or more) names

    Paul Pluzhnikov wrote:
    > phil-news-nospam@ipal.net writes:
    >
    >> Is there a way to create functions in a library so that references can be
    >> made to that function using two different symbol names (e.g. an alias),

    >
    > Yes, on some platforms.
    >
    > On Linux (and other ELF platforms with gcc-3.x), do this:
    >
    > void foo() { }
    > void bar() __attribute__((alias("foo")));


    Since function pointers can be used just like functions, could he not
    also simply export pointers with any compiler/platform? I don't see why
    the calling program should ever have to know or care whether the symbols
    are in the text or data sections.

    HT

  6. Re: one function (in a library) - two (or more) names

    Henry Townsend writes:

    >> void foo() { }
    >> void bar() __attribute__((alias("foo")));

    >
    > Since function pointers can be used just like functions, could he not
    > also simply export pointers with any compiler/platform?


    No, this doesn't work on e.g. AIX/PowerPC:

    $ cat alias1.c
    void foo() { }
    void (*bar)() = &foo;

    $ cat main.c
    int main() { foo(); bar(); return 0; }

    $ cc -c main.c alias1.c
    $ cc main.o alias1.o
    ld: 0711-317 ERROR: Undefined symbol: .bar
    ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.

    $ dump -tv alias1.o | egrep 'foo|bar'
    [12] m 0x00000000 .text 1 extern .foo
    [16] m 0x00000028 .data 1 extern foo
    [18] m 0x00000020 .data 1 unamex foo
    [20] m 0x00000034 .data 1 extern bar
    [22] m 0x00000024 .data 1 unamex bar

    $ dump -tv main.o | egrep 'foo|bar'
    [20] m 0x00000000 undef 1 extern .foo
    [22] m 0x00000000 undef 1 extern .bar

    As you can see, on that platform .text function and .data pointer
    to it are quite different.

    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  7. Re: one function (in a library) - two (or more) names

    Paul Pluzhnikov writes:

    > Henry Townsend writes:
    >
    >> Since function pointers can be used just like functions, could he not
    >> also simply export pointers with any compiler/platform?

    >
    > No, this doesn't work on e.g. AIX/PowerPC:


    Actually, this doesn't work on *any* platform -- the syntax for
    calling function through function pointer is the same, but the code
    compiler writes it totally different.

    So on e.g. Linux, the same code links fine, but then crashes when
    the program jumps into the middle of the data segment:

    $ gcc -g main.c alias1.c && gdb -q ./a.out
    (gdb) r

    Program received signal SIGSEGV, Segmentation fault.
    0x804942c in force_to_data ()
    (gdb) bt
    #0 0x804942c in force_to_data ()
    #1 0x80483bd in main () at main.c:1


    Cheers,
    --
    In order to understand recursion you must first understand recursion.
    Remove /-nsp/ for email.

  8. Re: one function (in a library) - two (or more) names

    On Sat, 02 Jun 2007 21:47:06 -0700 Paul Pluzhnikov wrote:
    | Paul Pluzhnikov writes:
    |
    |> Henry Townsend writes:
    |>
    |>> Since function pointers can be used just like functions, could he not
    |>> also simply export pointers with any compiler/platform?
    |>
    |> No, this doesn't work on e.g. AIX/PowerPC:
    |
    | Actually, this doesn't work on *any* platform -- the syntax for
    | calling function through function pointer is the same, but the code
    | compiler writes it totally different.

    It doesn't look all that much different to me:

    .file "main.c"
    .text
    .p2align 4,,15
    ..globl main
    .type main, @function
    main:
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    subl $16, %esp
    call foo
    call bar
    xorl %eax, %eax
    leave
    ret
    .size main, .-main
    .section .note.GNU-stack,"",@progbits
    .ident "GCC: (GNU) 3.4.6"

    But the fact that they are not different _is_ a problem.


    | So on e.g. Linux, the same code links fine, but then crashes when
    | the program jumps into the middle of the data segment:

    The program should be jumping to the function foo in the first call.
    The second call is a problem. It would be jumping to a pointer in the
    data segment. Ouch!

    If the compiler knew bar was a pointer to a function, rather than assuming
    it is a function, then the code would be different. It should be different.
    Then it would pick up a pointer out of the data segment, that points to
    a place in the text segment, that should be where the foo() entry point is.

    But a pointer to a function isn't a solution to what I wanted, anyway.
    It requires different code to use it. My goal is to make a library
    that be linked to by older programs using one set of names and newer
    programs using a different set of names, each compiled assuming only
    "their" library would be utilized. And I don't want to overly bloat
    that library in so doing (e.g. no functions that call other functions
    to fake an alias, and most certainly no duplicate functions).

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-06-03-1103@ipal.net |
    |------------------------------------/-------------------------------------|

  9. Re: one function (in a library) - two (or more) names

    On Sat, 02 Jun 2007 21:32:21 -0400 Henry Townsend wrote:

    | Since function pointers can be used just like functions, could he not
    | also simply export pointers with any compiler/platform? I don't see why
    | the calling program should ever have to know or care whether the symbols
    | are in the text or data sections.

    In C source, yes, a pointer can be used like a function. But the compiler
    needs to know that it is a pointer in the first place, by being declared
    as such and defined so it is known where to get the pointer value. The
    compiler will generate different code that adds a level of indirection to
    the calling sequence.

    My goal is for an already compiled program that expects one name to be the
    name of a function in a library to work, as well as a different already
    compile program that expects a different name to be the name of the very
    same function in a library to also work, without duplicating the function
    and without adding a stub function under one name to call the other. Both
    programs were already compiled anticipating only the name they know of to
    be the name of that function. The idea is that it is a transition method
    so that older programs expecting older names do not need to be recompiled.

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-06-03-1113@ipal.net |
    |------------------------------------/-------------------------------------|

  10. Re: one function (in a library) - two (or more) names

    On Sat, 02 Jun 2007 21:47:06 -0700 Paul Pluzhnikov wrote:
    | Paul Pluzhnikov writes:
    |
    |> Henry Townsend writes:
    |>
    |>> Since function pointers can be used just like functions, could he not
    |>> also simply export pointers with any compiler/platform?
    |>
    |> No, this doesn't work on e.g. AIX/PowerPC:
    |
    | Actually, this doesn't work on *any* platform -- the syntax for
    | calling function through function pointer is the same, but the code
    | compiler writes it totally different.

    And the compiler needs to know it is a pointer to a function, too.
    Without that information, it assumes it is an ordinary function.
    A linker that refuses to let a reference to a function be resolved
    with a symbol exported from data would be a feature, IMHO.

    Example generated code on ARM (Linux/GCC):
    ================================================== ===========================
    -bash-2.05b# cat > main.c
    int abc();
    int (*def)();
    int (*ghi)();
    int main() {
    abc();
    def();
    (*ghi)();
    return 0;
    }
    -bash-2.05b# gcc -O3 -S -o main.s main.c
    -bash-2.05b# cat main.s
    .file "main.c"
    .text
    .align 2
    .global main
    .type main, %function
    main:
    @ args = 0, pretend = 0, frame = 0
    @ frame_needed = 0, uses_anonymous_args = 0
    str lr, [sp, #-4]!
    bl abc
    ldr r3, .L2
    mov lr, pc
    ldr pc, [r3, #0]
    ldr r2, .L2+4
    mov lr, pc
    ldr pc, [r2, #0]
    mov r0, #0
    ldr pc, [sp], #4
    ..L3:
    .align 2
    ..L2:
    .word def
    .word ghi
    .size main, .-main
    .comm def,4,4
    .comm ghi,4,4
    .ident "GCC: (GNU) 3.4.1 20040714 (TimeSys 3.4.1-7)"
    -bash-2.05b# gcc -O3 -c -o main.o main.c
    -bash-2.05b# objdump -d main.o

    main.o: file format elf32-bigarm

    Disassembly of section .text:

    00000000
    :
    0: e52de004 str lr, [sp, #-4]!
    4: ebfffffe bl 4
    8: e59f3018 ldr r3, [pc, #24] ; 28 <.text+0x28>
    c: e1a0e00f mov lr, pc
    10: e593f000 ldr pc, [r3]
    14: e59f2010 ldr r2, [pc, #16] ; 2c <.text+0x2c>
    18: e1a0e00f mov lr, pc
    1c: e592f000 ldr pc, [r2]
    20: e3a00000 mov r0, #0 ; 0x0
    24: e49df004 ldr pc, [sp], #4
    ...
    -bash-2.05b#
    ================================================== ===========================


    Example generated code on x86 (Linux/GCC):
    ================================================== ===========================
    phil@varuna:/home/phil 70> cat > main.c
    int abc();
    int (*def)();
    int (*ghi)();
    int main() {
    abc();
    def();
    (*ghi)();
    return 0;
    }
    phil@varuna:/home/phil 71> gcc -O3 -S -o main.s main.c
    phil@varuna:/home/phil 72> cat main.s
    .file "main.c"
    .text
    .p2align 4,,15
    ..globl main
    .type main, @function
    main:
    pushl %ebp
    movl %esp, %ebp
    subl $8, %esp
    andl $-16, %esp
    subl $16, %esp
    call abc
    call *def
    call *ghi
    xorl %eax, %eax
    leave
    ret
    .size main, .-main
    .comm def,4,4
    .comm ghi,4,4
    .section .note.GNU-stack,"",@progbits
    .ident "GCC: (GNU) 3.4.6"
    phil@varuna:/home/phil 73> gcc -O3 -c -o main.o main.c
    phil@varuna:/home/phil 74> objdump -d main.o

    main.o: file format elf32-i386

    Disassembly of section .text:

    00000000
    :
    0: 55 push %ebp
    1: 89 e5 mov %esp,%ebp
    3: 83 ec 08 sub $0x8,%esp
    6: 83 e4 f0 and $0xfffffff0,%esp
    9: 83 ec 10 sub $0x10,%esp
    c: e8 fc ff ff ff call d
    11: ff 15 00 00 00 00 call *0x0
    17: ff 15 00 00 00 00 call *0x0
    1d: 31 c0 xor %eax,%eax
    1f: c9 leave
    20: c3 ret
    phil@varuna:/home/phil 75>
    ================================================== ===========================

    --
    |---------------------------------------/----------------------------------|
    | Phil Howard KA9WGN (ka9wgn.ham.org) / Do not send to the address below |
    | first name lower case at ipal.net / spamtrap-2007-06-03-1138@ipal.net |
    |------------------------------------/-------------------------------------|

+ Reply to Thread