From owner-svn-src-head@freebsd.org Wed Jan 13 11:58:39 2016 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5F803A804E8; Wed, 13 Jan 2016 11:58:39 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail108.syd.optusnet.com.au (mail108.syd.optusnet.com.au [211.29.132.59]) by mx1.freebsd.org (Postfix) with ESMTP id 2901A1185; Wed, 13 Jan 2016 11:58:38 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c211-30-166-197.carlnfd1.nsw.optusnet.com.au (c211-30-166-197.carlnfd1.nsw.optusnet.com.au [211.30.166.197]) by mail108.syd.optusnet.com.au (Postfix) with ESMTPS id B16BA1A2C46; Wed, 13 Jan 2016 22:58:36 +1100 (AEDT) Date: Wed, 13 Jan 2016 22:58:35 +1100 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Konstantin Belousov cc: Bruce Evans , src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: Re: svn commit: r293792 - head/sys/boot/uboot/lib In-Reply-To: <20160113091418.GD72455@kib.kiev.ua> Message-ID: <20160113215530.Y2397@besplex.bde.org> References: <201601130022.u0D0MCWu029299@repo.freebsd.org> <20160113142527.U1277@besplex.bde.org> <20160113091418.GD72455@kib.kiev.ua> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=PfoC/XVd c=1 sm=1 tr=0 a=KA6XNC2GZCFrdESI5ZmdjQ==:117 a=PO7r1zJSAAAA:8 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=JzwRw_2MAAAA:8 a=kj9zAlcOel0A:10 a=ma8Wq6YzU5W2H2qhuqAA:9 a=riDA3dTC9GVwh4WG:21 a=KZbqmv61An97dh1V:21 a=CjuIK1q_8ugA:10 X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2016 11:58:39 -0000 On Wed, 13 Jan 2016, Konstantin Belousov wrote: > On Wed, Jan 13, 2016 at 03:03:07PM +1100, Bruce Evans wrote: >> Oops. It is only declared in outside of the kernel. >> Only __uintfptr_t is always declared by sys/types.h. > > So what is the intended use of the uintfptr_t type ? Looking at the > implementation only, I am unable to find a difference with uintptr_t. uintfptr_t is inded for functions. uintptr_t is an optional type that is only required to work for object pointers (only if it is a supported option of course). A similar type is needed for functions. I added uintfptr_t at much the same time that I added uintptr_t in 1998. Actually I added uintptr_t a little earlier under a different name, then changed it to be more like the draft C9x name uintptr_t. Unfortunately, standards haven't caught up with that yet. POSIX now uses various hacks near dlsym(). In the 2001 version it specifies impossible things if the arch is not a vax so that function pointers are too different from data pointers. It gives the bad example of casting dlsym() to a function pointer. dlsym() returns void *. dlopen() doesn't have this design error. It returns a handle. > Even on ia64 it is 64bit, which breaks my hypothesis about f standing > for 'function'. This might be a bug in ia64, but uintfptr_t works on it AFAIK. It is used for profiling. This is hard to test since profiling support is broken (profiling libraries not installed) on pluto. Function pointers have size 64 bits on ia64, so they can be represented in uint64_t's by memcpy()ing them. Casting them might give a different representation. I think ia64 really has fat function pointers but they are represented specially in 64-bit objects. E.g., in a small program, nm says that putchar is at 0x100000640, but when (putchar) is cast to int (*f)(int), the bits in f are 0x1000acbb0 and casting f to uint64_t doesn't change these bits. f is just a pointer to data containing the actual function address and possibly other data. (It points to .opd+16 which contains the same address that nm prints. There seem to be only 64 bits of address and no extra data there too.) binutils has to understand this of course. Profiling too. I think gprof doesn't understand this. It needs raw addresses represented in uintfptr_t with the same encoding that ELF uses. So uintfptr_t is not suitable for representing function pointers after all. It is for raw addresses or a simple encoding of them. Profiling hits record the "program counter". It is not obvious what this is when it might be represented indirectly. I think its raw register value is recorded, and this can only work if its value is a raw virtual address (if not, a table must be looked up to convert to something that gprof understand). Other data must use the same representation or convert to it. Data with C function pointers in it would need conversion. Bruce