Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 4 May 2013 23:08:25 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Yuri <yuri@rawbw.com>
Cc:        FreeBSD Hackers <hackers@freebsd.org>
Subject:   Re: What is the correct way to declare assembler global variable ?
Message-ID:  <20130504200825.GW3047@kib.kiev.ua>
In-Reply-To: <5184399C.9000805@rawbw.com>
References:  <518419B5.4000602@rawbw.com> <20130503203020.GR3047@kib.kiev.ua> <5184399C.9000805@rawbw.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--9vqSz5I27CpJbl/i
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Fri, May 03, 2013 at 03:26:36PM -0700, Yuri wrote:
> On 05/03/2013 13:30, Konstantin Belousov wrote:
> > Formal answer is for you to read about the .type directive in the GNU
> > as manual. Also, you need to read about either common symbols, or about
> > the .size directive.
> >
> > But, note that you cannot access hidden libc symbols from the code which
> > links to libc (dynamically). You probably need to re-consider higher-le=
vel
> > approach to your issue.
> >
>=20
> I didn't write this code. This is google-perftools-2.0 I am trying to por=
t.
> They added the procedure do_sbrk there (see below), that attempts to=20
> emulate what libc is doing for sbrk. It fails, they probably didn't test =
it.
> The idea is that they need to have hooks before and after sbrk call.
> I am not sure what the best approach would be here?
> How can the memory allocation library override sbrk in libc and still be=
=20
> able to attach to the original libc version of sbrk?
>=20
> On Linux there is another symbol __sbrk, and they just use it to conenct=
=20
> to the original sbrk. But there is no such thing of FreeBSD.
>=20
> Yuri
>=20
>=20
> static inline void* do_sbrk(intptr_t increment) {
>    void* curbrk =3D 0;
>=20
> #if defined(__x86_64__) || defined(__amd64__)
> # ifdef PIC
>    __asm__ __volatile__(
>        "movq .curbrk@GOTPCREL(%%rip), %%rdx;"
>        "movq (%%rdx), %%rax;"
>        "movq %%rax, %0;"
>        : "=3Dr" (curbrk)
>        :: "%rdx", "%rax");
> # else
>    __asm__ __volatile__(
>        "movq .curbrk(%%rip), %%rax;"
>        "movq %%rax, %0;"
>        : "=3Dr" (curbrk)
>        :: "%rax");
> # endif
> #else
>    __asm__ __volatile__(
>        "movl .curbrk, %%eax;"
>        "movl %%eax, %0;"
>        : "=3Dr" (curbrk)
>        :: "%eax");
> #endif
>=20
>    if (increment =3D=3D 0) {
>      return curbrk;
>    }
>=20
>    char* prevbrk =3D static_cast<char*>(curbrk);
>    void* newbrk =3D prevbrk + increment;
>=20
>    if (brk(newbrk) =3D=3D -1) {
>      return reinterpret_cast<void*>(static_cast<intptr_t>(-1));
>    }
>=20
>    return prevbrk;
> }
>=20
> extern "C" void* sbrk(intptr_t increment) __THROW {
>    MallocHook::InvokePreSbrkHook(increment);
>    void *result =3D do_sbrk(increment);
>    MallocHook::InvokeSbrkHook(result, increment);
>    return result;
> }

So all the code needs is to call hooks before and after the sbrk call,
right ?

For the !PIC case, what is cited above would probably work, but it requires
that libc is also linked static.

For the dynamic case, it should be enough to use the dlsym(RTLD_NEXT,
"sbrk") to get the pointer to interposed symbol in the wrapper. It
assumes that the library which interposes sbrk is loaded before libc,
but it is relatively non-trivial to fail this. Something along the
lines, obviously not even compiled:

#ifdef PIC
void *
sbrk(intptr_t incr)
{
	static void *(*libc_sbrk)(intptr_t);
	void *ret;

	if (libc_sbrk =3D=3D NULL)
		libc_sbrk =3D dlsym(RTLD_NEXT, "sbrk");
	sbrk_pre_hook(incr);
	ret =3D libc_sbrk(incr);
	sbrk_post_hook(ret, incr);
	return (ret);
}
#endif

The sample is in fact thread-safe, or rather, not any more unsafe than
an sbrk() use itself.

--9vqSz5I27CpJbl/i
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (FreeBSD)

iQIcBAEBAgAGBQJRhWq4AAoJEJDCuSvBvK1BtZYP/0x7EZBlJnFGJEZvrNWpp2sf
uErlVeDcDj3vi7b9V4YUD/Hue6gQwIT5+mpYqjzemkX8rcwnjDfZ0QzQnwu3C94x
g4wH6FbZ6BAV20a8yj/wVN8KbtYHcPDHyCUc/D62PcFFIy3+oM77Gm/1PlqlxOn/
rjcmaI6gbFSzcl22wtC4e8MCP08AZty8D8mRGlNDMV2F6Onx9OB6E8QelbTzlAYe
GQMAgvpLQnZkB+DqSg+CLmkxQ04r03dueVmp8P7DqsQfOj97HKMbLJmZN7jVXD8r
60XjH5o/ju/TYphWdm7dHHWBtw3hZXZ6coeZowAZg3I+qRzC9RjY1IDiPzDO8pdT
wN/9qNZxdegyuY3qGMwO2PlFvsguIKHnV3vzBNIzMgsme+mcl362aLkYVSJ6UDWa
SQfrSofamfc8ADgC1xoaGPdurBqDEPxhPZKKVlfm4BQmnFrs4mRwUVCvuestel7b
nAkgSMBKVFe+FvhxLfGJQcS3i4dfUiAp7PCE+5fR9vhd5KvxP91JN+2/9kmlEp/z
Ay3GVNlpvgt+3dMhUHSthuTF1HVRyyui8+I+dv3liC3whXAlfutTjQPOjXtoHFXf
4o6eUQ56Qopo/gnznOdMnwCHu+9/xXyVOfZKX3wtfJuYJ2FJSFYoM9pPiRn2tBFY
NbNtEDFGwd2liHIDv56Z
=gkMx
-----END PGP SIGNATURE-----

--9vqSz5I27CpJbl/i--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130504200825.GW3047>