|
From: Jeremy F. <je...@go...> - 2005-03-31 21:26:57
|
Nicholas Nethercote wrote:
> 2. Copy a libc into Valgrind, eg. uClibc.
>
> Pros: as for (1)
> Cons: lots of extra code, much of it unused
Well, the nice thing about uClibc is that its very configurable, and its
easy to drop stuff you don't need.
> AIUI, Julian favours (3), Jeremy favours either (1) or (2). I'm
> leaning towards (3).
>
> I've undoubtedly oversimplified the issues involved and missed out
> some important details. Anyone care to add their two cents? I figure
> it's a good idea to discuss this and come to some sort of
> conclusion/agreement before too much implementation effort occurs.
I definitely understand the appeal of 3, and I don't object too strongly
if we go that way, but I think we should really avoid wasting effort.
Every line of code is a liability, and if we're going to maintain code,
it had better pay for itself.
It seems to me there are four classes of functions:
1. very simple utility functions, like str* & mem*, atoX, etc
2. portable but complex things, like formatted string handling (*printf)
3. allocation
4. kernel/syscall stuff
I also see there are two distinct implementation decisions:
1. whether we use standard APIs for these various functions
2. whether we use our own implementation or someone else's (which can
either mean using the system's installed library, or including
another implementation within the Valgrind source).
(Naturally deciding to use someone else's implementation in 2 tends to
strongly suggest we'll use a standard API.)
The decision about what implementation to use can be made independently
for each class of library function:
1. simple utilities
1. Our implementations are functionally identical to their libc
counterparts (or should be if they're not). There are no
problems with the libc API for our purposes, so we should
just use it as is. This means dropping the VG_() prefix and
using standard function names.
2. There's no benefit to having our own implementations. On
the other hand, they already exist, and they're easy to
maintain.
2. formatting
1. Our formatting APIs are very similar to the standard ones;
we probably don't win much by using different names.
2. In many ways, our private implementations of formatting are
pretty limited compared to the standard onces; for example
there's no snprintf (only sprintf), which leads to a rare
but persistent series of buffer-overrun bugs; a limited
implementation of the standard formatting characters; and
clunky ways of doing IO (all the character-at-a-time
unbuffered IO is a bit of an eyesore). On the other hand,
we have some useful extra formats, like %y for symbolic
expansion of an address.
3. allocation
1. Our allocation model is basically the same as libc's, with
the added complexity of arenas. We're really only using the
arenas as a crude kind of memory profiling mechanism, with
sort-of typing (since you need to know the arena a pointer
came from to be able to free it). I'm not sure we get much
value from the arena stuff; if we dropped it, we would have
an exact analogue of malloc/free (which is what the tools
use anyway).
2. We'll always need to control memory use carefully, so we
need to either control the malloc/free layer, or the
underlying low-level allocator (ie, if we used a libc
malloc/free, but controlled where it gets its memory from).
4. syscall interfaces
1. There are two kinds of syscall we make: those which are on
behalf of the client, and those we need for ourselves. The
former are almost entirely done in one place
(VGA_(client_syscall)), with a couple exceptions; we care a
lot about exactly how these are implemented. The latter, we
don't care too much, so long as they interact well with the
client's uses. I guess this is a bit of a wash.
2. The syscall interface is going to be the hardest of these
three to port; it could well be a major issue for some
operating systems which don't document that layer at all;
using the native libraries would be a huge boon. The main
API problem with using libc is the global nature of errno;
there are various ways of fixing this by making it
thread-local data, but this gets messy and thread-library
specific.
Hm, so I guess what I'm thinking is:
* That that while it is a waste of effort to implement our own libc,
the libc API isn't very good for us. We've got masses of buffer
overrun and other bugs lurking in there, and the libc APIs make it
very difficult to avoid them. We should have our own libraries
for things like formatting, but they should only be vaguely
modelled on libc's formatting library. Any use of str* should be
viewed with suspicion; a better string structure would go a long
way to help.
* I'd like to open the discussion about dropping arena_* functions,
and just using a plain malloc/free-like interface for all
allocation. I don't see us getting much benefit from them, and
they add a low level of pervasive complexity all over the place
(for example, any function which allocates memory on behalf of
anyone else needs to take an extra arena argument).
* I guess its hard to avoid having our own syscall interface
implementation, though I really don't like the name of "kal".
There should be *no* abstraction in there; it needs to be an
exceedingly thin layer. How about "kil"?
J
|
|
From: Julian S. <js...@ac...> - 2005-03-31 14:13:17
|
On Thursday 31 March 2005 05:35, Nicholas Nethercote wrote: > On Wed, 30 Mar 2005, Tom Hughes wrote: > >> Instead, it would be better to put the Kal module/subsystem > >> in its own directory, kal, and put all the arch/os specific bits > >> just for Kal in there: > >> > >> kal/pub_core_kal.h -- services exported from kal; core but not > >> tools may use these > >> kal/pub_tool_kal.h -- services exported from kal; both core and > >> tools may use these > >> > >> kal/kal-x86-linux.c -- x86-linux specific implementation > >> kal/kal-amd64-linux.c -- amd64-linux specific implementation > >> kal/any_other_name.c -- generic implementation > (*) > Hmm... we were just discussing how having all the arch-specific code in > one module/directory wasn't really the right thing to do -- that it's > better to follow modules boundaries, and possibly have some arch-specific > code in each module. > > Isn't there a similar situation here? Ie. really the module (or modules) > here is our libc replacement or 'utility' module(s) or whatever you want > to call it. In which case we shouldn't have a separate kal/ directory > just for the arch-specific things. Does that make sense? Uh ... confused. The above proposal, and what Tom has done, does indeed accord with the para marked (*). It's just that for kal there may not be much generic code, and so perhaps kal/any_other_name.c might be a bit thin, but in principle it still exists. Am I missing something? I suppose there's an ambiguity -- as yet unresolved -- as to whether the vanilla stuff like VG_(strlen) etc should be in kal, in which case it would have to be in the vanilla parts of kal, or not. Personally I don't think so; strlen et al are just utility functions and have nothing to do with the kernel interface. To say it another way, the standard libc interface provides both vanilla utilities and kernel wrappers, and we are considering, at least, splitting that interface into two different parts. J |
|
From: Nicholas N. <nj...@cs...> - 2005-03-31 17:31:34
|
On Thu, 31 Mar 2005, Julian Seward wrote: > (*) >> Hmm... we were just discussing how having all the arch-specific code in >> one module/directory wasn't really the right thing to do -- that it's >> better to follow modules boundaries, and possibly have some arch-specific >> code in each module. >> >> Isn't there a similar situation here? Ie. really the module (or modules) >> here is our libc replacement or 'utility' module(s) or whatever you want >> to call it. In which case we shouldn't have a separate kal/ directory >> just for the arch-specific things. Does that make sense? > > Uh ... confused. The above proposal, and what Tom has done, does > indeed accord with the para marked (*). It's just that for kal there > may not be much generic code, and so perhaps kal/any_other_name.c > might be a bit thin, but in principle it still exists. In that case, shouldn't the module be called "libc" or "Utility" or something, instead of "KAL"? Perhaps the term "kernel abstraction layer" is confusing, since it gives the idea too much weight. Do we need a separate "kernel abstraction layer", or do we just need a libc/utility module which happens to have some (possibly many) arch/OS/platform specific bits? I'm not sure if I've explained that any more clearly. N |
|
From: Nicholas N. <nj...@cs...> - 2005-03-31 14:48:20
|
On Thu, 31 Mar 2005, Tom Hughes wrote: > I've got an updated patch now - it's getting a bit large so I've > gzipped it and put it on the web at: > > http://www.compton.nu/kal.patch.gz > > It builds on x86 and amd64. There is still work to be done removing > the vki structures from the kal interface but the error handling is > there and the stub routines in mylibc have been removed. > > I had to move the tool header file to the main includes directory > so the tools could see it. Which header file is that? tool.h is already in include/ ... N |
|
From: Julian S. <js...@ac...> - 2005-04-01 13:42:10
|
> > I've undoubtedly oversimplified the issues involved and missed out
> > some important details. Anyone care to add their two cents? I figure
> > it's a good idea to discuss this and come to some sort of
> > conclusion/agreement before too much implementation effort occurs.
>
> I definitely understand the appeal of 3, and I don't object too strongly
> if we go that way, but I think we should really avoid wasting effort.
> Every line of code is a liability, and if we're going to maintain code,
> it had better pay for itself.
In reality we need a hybrid of 2 (import a different libc) and 3
(roll our own). uCLibc, whilst way smaller than glibc, is still
huge -- importing it all would dwarf our own code base.
Basically the only thing that bothers me is dlopen etc all. All
the rest are harmless, unless anyone can find any other large heavy
objects hidden in the undergrowth.
I'm not crazy enough to suggest we should write our own ldso facility.
Far from it. Much better to see if we can easily saw off ldso from
(eg) uCLibc, then ringfence it adequately so as to guarantee it won't
screw us up in some obscure way. Pretty much the same way the
demangler is done.
I had a look at the uCLibc-0.9.27 sources just now, and I must say
that looks promising. I am a little concerned not to see an amd64
directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it
doesn't support amd64?
> 3. allocation
> 1. Our allocation model is basically the same as libc's, with
> the added complexity of arenas. We're really only using the
> arenas as a crude kind of memory profiling mechanism,
The arenas differ also in the size of the allocation redzones. This
is used by {mem,addr}check -- client allocations come from an arena
with big redzones, whilst the rest of V uses small or zero redzones
for size efficiency.
I like having the arenas; it allows us to crudely profile space use,
as you say; it also makes it easier to ensure that misuse of space
acquired from one arena (writing off the end of blocks) does not
screw up stuff in other arenas. I don't know if that's useful or
not in practice.
Yeh, having to pass around arena tags isn't the best. Not convinced
the extra hassle is a big deal though.
> the libc API isn't very good for us.
Sure. I also prefer not to inherit API stupidity from libc if
possible.
J
|
|
From: Nicholas N. <nj...@cs...> - 2005-04-01 13:48:39
|
On Fri, 1 Apr 2005, Julian Seward wrote:
> I had a look at the uCLibc-0.9.27 sources just now, and I must say
> that looks promising. I am a little concerned not to see an amd64
> directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it
> doesn't support amd64?
And I believe uCLibc is Linux-only...
>> 3. allocation
>> 1. Our allocation model is basically the same as libc's, with
>> the added complexity of arenas. We're really only using the
>> arenas as a crude kind of memory profiling mechanism,
>
> The arenas differ also in the size of the allocation redzones. This
> is used by {mem,addr}check -- client allocations come from an arena
> with big redzones, whilst the rest of V uses small or zero redzones
> for size efficiency.
Yes, the redzones are one of the most important reasons for having our own
allocator.
N
|
|
From: Erik A. <and...@co...> - 2005-04-01 17:15:16
|
On Fri Apr 01, 2005 at 07:48:32AM -0600, Nicholas Nethercote wrote: > On Fri, 1 Apr 2005, Julian Seward wrote: > > >I had a look at the uCLibc-0.9.27 sources just now, and I must say > >that looks promising. I am a little concerned not to see an amd64 > >directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it > >doesn't support amd64? > > And I believe uCLibc is Linux-only... Currently uCLibc is indeed Linux only. Thus far there has been little interest or effort towards supporting alternatives, since glibc seems to hace that covered. We focus on being small and correct. Actually, someone did port to libgloss, so uClibc could also run on bare metal but that work has never been merged. -Erik -- Erik B. Andersen http://codepoet-consulting.com/ --This message was written using 73% post-consumer electrons-- |
|
From: Julian S. <js...@ac...> - 2005-04-01 17:19:06
|
Erik Thanks for the info. So, do you support amd64 on Linux? It's not clear from what you said. J On Friday 01 April 2005 18:14, Erik Andersen wrote: > On Fri Apr 01, 2005 at 07:48:32AM -0600, Nicholas Nethercote wrote: > > On Fri, 1 Apr 2005, Julian Seward wrote: > > >I had a look at the uCLibc-0.9.27 sources just now, and I must say > > >that looks promising. I am a little concerned not to see an amd64 > > >directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it > > >doesn't support amd64? > > > > And I believe uCLibc is Linux-only... > > Currently uCLibc is indeed Linux only. Thus far there has been > little interest or effort towards supporting alternatives, since > glibc seems to hace that covered. We focus on being small and > correct. Actually, someone did port to libgloss, so uClibc could > also run on bare metal but that work has never been merged. > > -Erik > > -- > Erik B. Andersen http://codepoet-consulting.com/ > --This message was written using 73% post-consumer electrons-- |
|
From: Erik A. <and...@co...> - 2005-04-01 17:38:13
|
On Fri Apr 01, 2005 at 06:18:31PM +0100, Julian Seward wrote: > > Erik > > Thanks for the info. > > So, do you support amd64 on Linux? It's not clear from what > you said. There are a few architecture specific areas in uClibc. Basic architecture support means you can staticly link applications. That generally just requires an implementation for crti.o, crtn.o, crt1.o, and any overrides for generic syscalls that are different for the architecture (typically just a few syscalls such as brk, setjmp, longjmp, vfork, clone). This part is done so staticly linked apps alledgedly work. I say alledgedly since I lack amd64 hardware and thus have never tested it. For more complete architecture support, one should add the needed bits for libpthread (i.e. testandset and compare_and_swap). For improved architecture support, one should then add optimized string functions (i.e. strcpy, memcpy, etc). This is not critical, but does tend to improve performance. This has not been done for x86_64. Finally, the most difficult bit of architecture specific code is adding ldso support. This has not been done for x86_64. -Erik -- Erik B. Andersen http://codepoet-consulting.com/ --This message was written using 73% post-consumer electrons-- |
|
From: Julian S. <js...@ac...> - 2005-04-01 15:04:09
|
On Friday 01 April 2005 14:48, Nicholas Nethercote wrote: > On Fri, 1 Apr 2005, Julian Seward wrote: > > I had a look at the uCLibc-0.9.27 sources just now, and I must say > > that looks promising. I am a little concerned not to see an amd64 > > directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it > > doesn't support amd64? > > And I believe uCLibc is Linux-only... Umm. Well, that's a(nother) good reason not to snarf it as-is :-) But we might still be able to saw off the ldso parts and route any syscall requirements it has via Kal; then it would [in theory :-] still work on non-Linux platforms. Eric, what's the situation with uCLibc on amd64? Does/will the ldso stuff support amd64? What about ppc32 and ppc64? J |
|
From: Erik A. <and...@co...> - 2005-04-01 17:27:16
|
On Fri Apr 01, 2005 at 04:03:32PM +0100, Julian Seward wrote: > On Friday 01 April 2005 14:48, Nicholas Nethercote wrote: > > On Fri, 1 Apr 2005, Julian Seward wrote: > > > I had a look at the uCLibc-0.9.27 sources just now, and I must say > > > that looks promising. I am a little concerned not to see an amd64 > > > directory hanging off uClibc-0.9.27/ldso/ldso; does that mean it > > > doesn't support amd64? > > > > And I believe uCLibc is Linux-only... > > Umm. Well, that's a(nother) good reason not to snarf it as-is :-) It rather depends on your goals. Thus far, linux only has been sufficient. The structure is there such that uClibc could be ported, should interested parties care to do the needed work. > But we might still be able to saw off the ldso parts and route any > syscall requirements it has via Kal; then it would [in theory :-] > still work on non-Linux platforms. The ldso license is such that you are more than welcome to do so should you feel the need. Only a few syscalls are needed for ldso, and they are seperated out into a single header file. As long as the target platform does ELF, uClibc's ldso should work fine. We've been working on some major changes and cleanup in the last couple of weeks. Which is to say, half the architectures are currently broken, but I hope to get all sorted out in the next couple of days. > Eric, what's the situation with uCLibc on amd64? Does/will the ldso > stuff support amd64? What about ppc32 and ppc64? A point of pedantry - s/Eric/Erik/ :) It will support amd64 when interested parties do the needed work. There is preliminary architecture support in place in SVN, but support of ldso has not even begun. Lacking an amd64 system, I havn't personally been very motivated. Linux/ppc32 works great. As with amd64, I lack a ppc64 capable system and thus have not persued the port. A basic static linking only port is really pretty easy to do. Getting ldso working takes a lot more work though. Alledgedly a contract I am working on will provide me with an Apple G5 in the next few months, which will no doubt get me working on that port as time permits. -Erik -- Erik B. Andersen http://codepoet-consulting.com/ --This message was written using 73% post-consumer electrons-- |
|
From: Julian S. <js...@ac...> - 2005-04-01 17:46:44
|
> A point of pedantry - s/Eric/Erik/ :) Sorry about that :) -- I noticed it just after I clicked 'send'. > It will support amd64 when interested parties do the needed work. > There is preliminary architecture support in place in SVN, but > support of ldso has not even begun. Lacking an amd64 system, I > havn't personally been very motivated. > [...] Hmm, ok. Back to the drawing board. I might stare at the ldso stuff to see how hard it would be to get it to work on amd64. We're going to need that functionality one way or the other; and the good thing about working with uclibc is that we'd only presumably have to fill in the amd64-specific holes in ldso; the generic infrastructure is already all there. Correct? J |
|
From: Bryan O'S. <bo...@se...> - 2005-04-02 06:30:12
|
On Fri, 2005-04-01 at 18:46 +0100, Julian Seward wrote: > Hmm, ok. Back to the drawing board. I might stare at the ldso > stuff to see how hard it would be to get it to work on amd64. If you need other amd64-specific stuff, you should look at klibc. It uses an unusual and non-standard dynamic linking mechanism, so that won't be useful to you, but the rest works. You may also want to look at rtldi for dynamic loading. I don't know how applicable to your needs it is, but it seems to be x86-specific again. <b |
|
From: Erik A. <and...@co...> - 2005-04-01 17:48:10
|
On Fri Apr 01, 2005 at 06:46:27PM +0100, Julian Seward wrote: > > It will support amd64 when interested parties do the needed work. > > There is preliminary architecture support in place in SVN, but > > support of ldso has not even begun. Lacking an amd64 system, I > > havn't personally been very motivated. > > [...] > > Hmm, ok. Back to the drawing board. I might stare at the ldso > stuff to see how hard it would be to get it to work on amd64. > We're going to need that functionality one way or the other; > and the good thing about working with uclibc is that we'd only > presumably have to fill in the amd64-specific holes in ldso; > the generic infrastructure is already all there. Correct? Yup -Erik -- Erik B. Andersen http://codepoet-consulting.com/ --This message was written using 73% post-consumer electrons-- |
|
From: Jeremy F. <je...@go...> - 2005-04-01 21:57:58
|
Julian Seward wrote:
>Umm. Well, that's a(nother) good reason not to snarf it as-is :-)
>But we might still be able to saw off the ldso parts and route any
>syscall requirements it has via Kal; then it would [in theory :-]
>still work on non-Linux platforms.
>
>
Not really. The dynamic linker is object-file and toolchain dependent,
so unless we want to force all platforms to use a specific
toolchain+object file format, we're going to have to work out how to
live with whatever the platform provides.
The dynamic linking for tools is hardly essential. At worst, we could
easily link the tool into stage2, and have a stage2 per tool. With the
cleanup of the tool interface, you could link all the tools into one
stage2 binary as well.
Loading and locating stage2 would remain a problem, but that's easier
since it happens before Valgrind takes control, and stage1 can make full
use of all the system libraries etc.
J
|
|
From: Nicholas N. <nj...@cs...> - 2005-04-01 22:35:03
|
On Fri, 1 Apr 2005, Jeremy Fitzhardinge wrote: >> Umm. Well, that's a(nother) good reason not to snarf it as-is :-) >> But we might still be able to saw off the ldso parts and route any >> syscall requirements it has via Kal; then it would [in theory :-] >> still work on non-Linux platforms. > > Not really. The dynamic linker is object-file and toolchain dependent, > so unless we want to force all platforms to use a specific > toolchain+object file format, we're going to have to work out how to > live with whatever the platform provides. > > The dynamic linking for tools is hardly essential. At worst, we could > easily link the tool into stage2, and have a stage2 per tool. With the > cleanup of the tool interface, you could link all the tools into one > stage2 binary as well. > > Loading and locating stage2 would remain a problem, but that's easier > since it happens before Valgrind takes control, and stage1 can make full > use of all the system libraries etc. And then we wouldn't need dlopen() at all, right? Hmm, that doesn't sound so bad. One problem is external tools, eg. Callgrind. Is there any other way to achieve the core/tool opening and connection without using dlopen()? N |
|
From: Jeremy F. <je...@go...> - 2005-04-01 23:32:24
|
Nicholas Nethercote wrote:
> And then we wouldn't need dlopen() at all, right?
Well, we'd still need it to get stage2 into the right place, unless we
can use some linker magic to get it there first shot; I've tried doing
this before, but its very hard to get right, and extremely hard to make
it work over a wide range of toolchain versions (and that's just
binutils). It would also have the same disadvantages of the current
non-PIE case. A dynamically placed stage2 is definitely preferred (at
least for 32-bit platforms; 64-bit should give us enough address space
to be able to place things statically without cramping anyone).
> Hmm, that doesn't sound so bad. One problem is external tools, eg.
> Callgrind. Is there any other way to achieve the core/tool opening
> and connection without using dlopen()?
Create a valgrind-core.o (or .a) and link callgrind against it, to
produce a stage2-callgrind.
J
|
|
From: Julian S. <js...@ac...> - 2005-06-26 01:50:40
|
[to continue an old discussion ..] >On Saturday 02 April 2005 00:32, Jeremy Fitzhardinge wrote: > Nicholas Nethercote wrote: > > And then we wouldn't need dlopen() at all, right? > > Well, we'd still need it to get stage2 into the right place, unless we > can use some linker magic to get it there first shot; I've tried doing > this before, but its very hard to get right, and extremely hard to make > it work over a wide range of toolchain versions (and that's just > binutils). Suppose stage2 is statically linked, including the relevant tool, and is linked to load at some non-standard address, the latter as at present. Then there would be no need for stage1 at all, and no need for address space padding/unpadding. Is that correct? J |
|
From: Jeremy F. <je...@go...> - 2005-06-30 20:07:15
|
Julian Seward wrote:
>Suppose stage2 is statically linked, including the relevant tool,
>and is linked to load at some non-standard address, the latter as
>at present. Then there would be no need for stage1 at all, and no
>need for address space padding/unpadding. Is that correct?
>
>
Pretty much. For usability you'd have a simple program to select the
right backend binary for a particular tool, and maybe for the
appropriate CPU type (so it can handle x86 and x86-64 in a
user-transparent way).
J
|