PATCH: Add ifunc attribute

H.J. Lu hjl.tools@gmail.com
Mon Jun 29 01:51:00 GMT 2009


On Sat, Jun 27, 2009 at 7:06 PM, Roland McGrath<roland@redhat.com> wrote:
>> On Fri, Jun 26, 2009 at 3:10 PM, Roland McGrath<roland@redhat.com> wrote:
>> >> along with its static Linux/ia32 binary. How do you
>> >> write a similar prog.C in C++ with your ifunc attribute
>> >> proposal?
>> >
>> > The only difference is using (Class::*) vs (*) in the return type of the
>> > foo_finder functions.  Did I missing something obvious?
>>
>> The one problem with using asm () for C++ name mangling is
>> it isn't easy to figure out what the assembly symbol one is.
>> If you change the function prototype, you have to figure
>> out the assembly name again.
>
> My suggestion did not involve asm.  I do not think it would be wise to have
> a feature where manual name-mangling is the only method available for C++.
>
>> class Foo
>> {
>> private:
>>   virtual void foo1 ()
>>     {
>>       printf ("I am %s\n", __PRETTY_FUNCTION__);
>>     }
>> public:
>>   virtual void  __attribute__ ((ifunc)) foo ()
>>     {
>>       return &Foo::foo1;
>>     }
>> };
>>
>> there is no such problem.
>
> In what I suggested this would be:
>
>    class Foo
>    {
>    private:
>      virtual void foo1 ()
>      {
>        printf ("I am %s\n", __PRETTY_FUNCTION__);
>      }
>    public:
>      virtual void foo ();
>    };
>    static void __attribute__ ((ifunc ("Foo::foo")))
>    (Foo::*foo_finder ()) ()
>    {
>      return &Foo::foo1;
>    }
>
> Note that foo_finder is static, so "foo_finder" would be a local symbol (or
> could in theory be renamed arbitrarily by the compiler, etc.), but this has

Static member function in C++ has global binding.

> no bearing on the "Foo::foo" mangled symbol (which is the STT_IFUNC).  Its
> visibility, binding, etc. are determined by the void Foo::foo ()
> declaration in scope.

What symbol name should compiler generate for "foo_finder"?
You may have many member functions named "foo" with different
prototypes.

> It could also be written:
>
>    class Foo
>    {
>    private:
>      virtual void foo1 ()
>      {
>        printf ("I am %s\n", __PRETTY_FUNCTION__);
>      }
>      static void __attribute__ ((ifunc ("foo")))
>      (Foo::*foo_finder ()) ()
>      {
>        return &Foo::foo1;
>      }
>    public:
>      virtual void foo ();
>    };
>
> (Though perhaps declaration order could require that "virtual void foo ();"
> be declared before the use of __attribute__ ((ifunc "foo")).  I don't know
> about that wrinkle of what makes most sense for C++.  In a C context, I
> would expect __attribute__ ((ifunc ("foo"))) to require that a prototype for
> foo already be in scope.)

How do you handle

class ifunc
{
private:
  int foo1 (int);
  int foo2 (float);

public:
  int foo (int);
  int foo (float);
  int bar (int);
  int bar (float);
};

int
__attribute__ ((ifunc))
ifunc::foo (int)
{
  return &ifunc::foo1;
}

int
__attribute__ ((ifunc))
ifunc::foo (float)
{
  return &ifunc::foo2;
}

int
ifunc::bar (int x)
{
  return foo (x);
}

int
ifunc::bar (float x)
{
  return foo (x);
}

> Note this use lets unadorned "foo" make sense in the attribute, for
> the actual STT_IFUNC symbol being mangled "void Foo::foo ()".
> OTOH, (without using visibility features et al) Foo::foo_finder is
> produced as a global symbol when that is not really required or desired.
>

I think the 3rd option is the most sensible for C++. I will create
an ifunc branch so that we can compare different approaches.

Thanks.


-- 
H.J.



More information about the Libc-alpha mailing list