public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
From: Nick Alcock <nick.alcock@oracle.com>
To: Joseph Myers <joseph@codesourcery.com>
Cc: <binutils@sourceware.org>
Subject: Re: [PATCH 00/19] libctf, and CTF support for objdump and readelf
Date: Fri, 03 May 2019 14:23:00 -0000	[thread overview]
Message-ID: <8736lvwr9p.fsf@esperi.org.uk> (raw)
In-Reply-To: <alpine.DEB.2.21.1905021508230.4027@digraph.polyomino.org.uk>	(Joseph Myers's message of "Thu, 2 May 2019 15:22:30 +0000")

[looking at your comments first because you were so very helpful last
 time I contributed to glibc. :) ]

(And thank you! I haven't done quite everything you suggested, at least
not yet, but the 90% I have done is entirely beneficial and you spotted
a lot of things I overlooked.)

On 2 May 2019, Joseph Myers spake thusly:

> This patch series introduces a dependency of binutils on libctf.
>
> This means libctf should be portable to the same range of hosts as 
> binutils, all of which can be used as hosts for cross toolchains for a 
> range of targets (ELF and non-ELF).  For example, it should be portable to 
> hosts such as MinGW or OS X.

Seems sensible. It might lose some functionality, though, at least to
start with. (Say, sharing string tables with the overarching container,
opening CTF files by handing them an fd to a containing binary, etc.
There are alternatives callers can use in all these cases.)

I'll probably arrange for the deduplicating linker plugin to be
ELF-only, at least to start with, because I have no way to test on
anything else, and it might always keep strings and symbols internal to
the CTF file rather than trying to share them with the enclosing binary,
until someone else contributes that sort of thing for non-ELF.

> Some apparent portability issues in this code include:
>
> * Use of dlfcn.h.  Such use in existing binutils code (e.g. bfd/plugin.c) 
> is conditional, to avoid trying to use it on hosts without that 
> functionality.

This was used by ancient code in the OpenSolaris days that endeavoured
to dlopen() zlib to avoid linking against it (why one would want to
avoid linking against zlib is opaque to me). No user these days:
dropped.

> * Use of sys/mman.h.  Again, mmap usage in existing code is appropriately 
> conditional.

We can fall back to copying or malloc in that situation, in most cases.

However, the CTF archive code would be made significantly more
complicated, more than cancelling out the implementation simplicity
which was one reason for using mmap() there in the first place. So for
now my no-mmap() CTF archive code just fails: callers can detect the
failure and fall back to storing CTF containers separately in that case.
(Both reading and writing fail symmetrically, so you aren't going to end
up creating containers you then can't read.)

If there are really still platforms relevant outside industrial museums
without mmap(), we can rethink this, but I bet there aren't, or that any
such platforms aren't going to be storing huge numbers of CTF containers
in any case. (The use case for this is if you have so many TUs that you
can't store one per section without risking blowing the 64K section
limit. Any machine new enough to be dealing with anything in that size
range is going to have mmap() as well, right? Or something we can use
instead of it with similar semantics...)


Note that it's only *creating* CTF archives without mmap() that is too
horrible to countenance. It is relatively easy to support reading CTF
archives on non-mmap-supporting systems, if quite inefficiently, so we
could arrange to fall back to read-and-copy in that case, allowing
people in cross environments to not need to worry about whether their
target supports mmap() before creating CTF archives. This might be a
reasonable middle ground, perhaps?


(Added fallbacks for mmap() in all cases but CTF archives: as noted
above, we can add fallbacks for archive usage, too, just not creation.)

(oh btw you missed a bit: we use pread() too, and badly, ignoring the
possibility of short reads or -EINTR returns. Fixing, and adding a
fallback for that as well.)

> * Use of sys/errno.h.  The standard name is errno.h.

Ancient historical wart: fixed, thank you! How did I miss that?!

> * Use of elf.h.  Non-ELF hosts won't have such a header.  You should be 
> working with the existing include/elf/*.h definitions of ELF data 
> structures in binutils.

This is all for build hosts that aren't ELF, right? I don't think we can
reasonably expect ctf_open() or ctf_fdopen() to work for anything but
raw CTF files on non-ELF hosts, given that by their very nature these
functions are getting CTF data out of ELF sections, and non-ELF formats
don't necessarily support anything like the named section concept ELF
has got at all.

The only other ELF-specificity is looking up types by symbol table
offset. Again, I don't know enough about non-ELF platforms to know if
this concept is even practical there, which would mean the data object
and function info sections would be empty on such hosts, and
ctf_lookup_by_symbol(), ctf_func_info() and ctf_func_args() would not
function or would be excluded from the set of exported symbols entirely.

This would reduce libctf's utility, but not eliminate it: external
systems can still look up types by name or CTF type ID even if they
can't do it by symbol.

It is possible that such things could be revived: all we'd need for a
given non-ELF platform would be a way to consistently split whatever
they use as a symbol table into an ordered list of data and function
objects that could be referenced by those CTF sections. However, for
now, this functionality is intrinsically ELF-only in the sense that
nobody has ever considered how it might work on non-ELF platforms and it
certainly has no users there.

However, for now we can do a little better than this: see below.

> * Use of gelf.h.  This seems to be something from some versions of libelf, 
> which isn't an existing build dependency of binutils at all (and given the 
> existence of multiple, incompatible versions of libelf, one should be wary 
> of depending on it).  The only gelf.h I have locally here is in a checkout 
> of prelink sources.  Again, use existing ELF structures in headers present 
> in binutils.

This is a historical thing: libelf was of course part of Solaris so its
usage was pervasive, even when unnecessary, as here. What we're actually
using is a few datatypes, nothing more: the Elf64_Sym, from <elf.h> (on
Linux, provided by glibc), the Elf*_GHdr and Elf*_SHdr, and the
primitive ELF-sized datatypes like Elf64_Word that those structures use.

I don't see any immediate replacement for most of this stuff in
binutils, even though I'd expect to find it: the Elf64_External_Sym's
members are entirely the wrong type (char arrays), and there doesn't
seem to be any common non-architecture-dependent structure with more
useful types at all!

Elf64_Internal_Sym is very bfd-specific (and I'm trying not to have
libctf depend on libbfd unnecessarily, since it needs little of its
functionality), and the code in readelf that mocks up an internal_sym
from file data spends almost all its time getting around the problem
that its datatypes are different from the (standard-guaranteed) data
types in the ELF file itself. This is more futzing about than seems sane
given that we're not using the rest of bfd at all.

So I'd rather find a way to do the simple 'get a bit of very simple data
out of an ELF file we have an fd to (symbol lookups and a couple of
section lookups)' without needing to rejig everything to use bfd just to
do that, particularly given that libctf's APIs that involve the caller
passing info corresponding to a section into libctf do not require the
caller to use bfd and I have not the least idea how to go from
data+size-and-no-fd to a bfd_asection (it's probably not possible).


I could just copy the (fairly small number of) relevant types from
glibc's installed elf.h header into the ctf internals (the license is
compatible, after all, as is the copyright ownership), using a different
(CTF-internal) name to avoid clashes causing trouble at build time.
Would that be acceptable?

This lets us operate unchanged on non-ELF hosts and when not targetting
ELF, and leave this code in and even functional in that situation: it
detects ELF files by their magic number, which will presumably never
match things passed in to ctf_open() on non-ELF targets, and nothing
would ever generate contents for the function info or data object
sections on such non-ELF targets either (until we figured out how to do
so), so the ELF-specific code involved in reading those sections is also
not a problem.

Adding more magic numbers for more executable types is possible: if we
started handling COFF or PE or Mach-O or something like that, we would
probably soon hit a stage where it would become useful to start using
some bfd abstractions, but I think the time is not yet. (I don't know
enough about these formats to know if they even *have* named sections.)

> * Use of byteswap.h and endian.h.  Such headers are not portably 
> available.  Note how byteswap.h usage in gold / elfcpp is appropriately 
> conditional.

Makes sense. I can easily arrange to use code like elfcpp does in that
case.

... (done.)

  parent reply	other threads:[~2019-05-03 14:23 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-30 22:57 Nick Alcock
2019-04-30 22:57 ` [PATCH 19/19] binutils: " Nick Alcock
2019-04-30 22:57 ` [PATCH 08/19] libctf: creation functions Nick Alcock
2019-04-30 22:57 ` CTF format overview Nick Alcock
2019-04-30 22:57 ` [PATCH 13/19] libctf: type copying Nick Alcock
2019-04-30 22:57 ` [PATCH 15/19] libctf: mmappable archives Nick Alcock
2019-04-30 22:57 ` [PATCH 01/19] include: new header ctf.h: file format description Nick Alcock
2019-05-01 16:57   ` Nick Clifton
2019-05-01 21:29     ` Jim Wilson
2019-05-03 11:15       ` Nick Alcock
2019-04-30 22:57 ` [PATCH 05/19] libctf: error handling Nick Alcock
2019-05-02 16:10   ` Nick Clifton
2019-05-03 19:31     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 02/19] include: new header ctf-api.h Nick Alcock
2019-05-02 15:07   ` Nick Clifton
2019-05-03 11:23     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 06/19] libctf: hashing Nick Alcock
2019-05-02 16:16   ` Nick Clifton
2019-05-03 19:33     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 10/19] libctf: ELF file opening Nick Alcock
2019-04-30 22:57 ` [PATCH 09/19] libctf: opening Nick Alcock
2019-04-30 22:57 ` [PATCH 03/19] libctf: lowest-level memory allocation and debug-dumping wrappers Nick Alcock
2019-05-02 15:29   ` Nick Clifton
2019-05-03 19:12     ` Nick Alcock
2019-04-30 22:57 ` [PATCH 12/19] libctf: lookups by name and symbol Nick Alcock
2019-04-30 22:57 ` [PATCH 14/19] libctf: library version enforcement Nick Alcock
2019-04-30 22:57 ` [PATCH 11/19] libctf: core type lookup Nick Alcock
2019-04-30 22:57 ` [PATCH 04/19] libctf: low-level list manipulation and helper utilities Nick Alcock
2019-05-02 16:04   ` Nick Clifton
2019-05-03 19:25     ` Nick Alcock
2019-04-30 22:58 ` [PATCH 18/19] libctf: build system Nick Alcock
2019-05-01  0:13 ` [PATCH 17/19] libctf: debug dumping Nick Alcock
2019-05-01  0:19 ` [PATCH 16/19] libctf: labels Nick Alcock
2019-05-01  1:57 ` [PATCH 07/19] libctf: implementation definitions related to file creation Nick Alcock
2019-05-01 16:02 ` [PATCH 00/19] libctf, and CTF support for objdump and readelf Nick Clifton
2019-05-01 16:16   ` Jose E. Marchesi
2019-05-03 10:47     ` Nick Alcock
2019-05-02 15:22 ` Joseph Myers
2019-05-03 12:33   ` Nick Clifton
2019-05-06 16:40     ` Nick Alcock
2019-05-08 14:34     ` Michael Matz
2019-05-08 16:01       ` Nick Clifton
2019-05-08 16:20         ` Nick Alcock
2019-05-03 14:23   ` Nick Alcock [this message]
     [not found]     ` <alpine.DEB.2.21.1905072117440.19308@digraph.polyomino.org.uk>
2019-05-08 11:39       ` Nick Alcock
2019-05-24  8:57     ` Pedro Alves
2019-05-24 16:05       ` Nick Alcock
2019-05-24 16:19         ` Pedro Alves
2019-05-24 20:09           ` Nick Alcock
2019-05-03 16:19 ` Florian Weimer
2019-05-03 19:45   ` Nick Alcock
2019-05-06 12:07     ` Florian Weimer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=8736lvwr9p.fsf@esperi.org.uk \
    --to=nick.alcock@oracle.com \
    --cc=binutils@sourceware.org \
    --cc=joseph@codesourcery.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).