This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Should strip discard the .ctf section ?
On 2019-10-07, Nick Alcock wrote:
On 7 Oct 2019, Rich Felker told this:
On Mon, Oct 07, 2019@08:34:00PM +0100, Nick Alcock wrote:
On 7 Oct 2019, Nick Alcock spake thusly:
> I have had people asking me to make .ctf a loaded segment, but in
> addition to having the same qualms as you about loading this section in
> and eating memory before it is in widespread use, I can see no way to do
> such a thing without a radical linker rearchitecture.
To reiterate:
- I am happy to make the CTF section loaded *if* someone can show me a
way to make this be the case without changing its format in ways that
impair its compactness and without having to rewrite basically the
entire linker in the process. In particular, it should still be able
to elide strings from the CTF-internal string table that are also
present in the ELF strtab, and it should still be able to have the
CTF-internal object and function info sections ordered such that they
are in the same order as the symbols in the ELF symtab (not yet
implemented in libctf, but implemented in GCC and wil be added to the
libctf side with no further ld/bfd changes needed).
I think this should be possible, but I don't yet know how. I think
it's worth trying to find the way to do it.
I nearly broke my brain trying to do so. I'd be immensely happy for
someone else to look :)
Whether .ctf has the SHF_ALLOC flag or not should not cause a drastic
change in the linker design. It seems .ctf has the dedup feature so
"Rules for Linking Unrecognized Sections" (which simply combines input
sections) does not apply. .ctf is an output section whose content is
synthesized by the linker, like .eh_frame, .got, .ARM.exidx, etc.
If .ctf has the SHF_ALLOC flag, and its size can vary with the addresses
of other sections. Then, computing its content should be an iterative
process. You may need to check lang_size_sections and the like.
The iterative framework is already there - architectures with thunks and
symbol assignments in linker scripts need it.
- On the contrary, making the CTF section stripped by default appears
to render it useless for most of its intended use cases: the whole
point of it is that it is so tiny that it doesn't need to be stripped
out. I *am* philosophically against this one.
Users who want to strip binaries typically really want the tools to do
what they say. They also tend to use utilities like sstrip that
aggressively remove parts of the file that are not part of the ELF
load-time semantics.
Well, I imagine that a completely different tool from strip would keep
doing just that. :)
strip defaults to --strip-all when no other --strip* or
--only-keep-debug is specified.
--strip-all is currently a superset of --strip-debug.
I argue that --strip-debug and --strip-all should remove non-SHF_ALLOC
.ctf . This is the behavior of the tool and expected by users.
.ctf should be considered a debug section. gcc -gt generates it. -g
options are used to customize debug info generation.
--strip-all removes .symtab and .strtab. If .ctf references .symtab but
is not stripped along with .symtab and .strtab, the resulting .ctf will
just be broken.
Different strip tools were made suggests that people are not happy with
the current --strip-all behavior. It is a misnomer. It should just
remove all non-SHF_ALLOC sections.
Requriring the strip utility to special-case .ctf
because you want it to be usable like a loadable section, but want to
avoid making it loadable because that's difficult to do in the
framework of BFD ld's implementation, is a bad hack.
Yeah, I was stuck between two cleft sticks here. Nothing *depends* on
.ctf being non-loaded -- we can make it loadable later -- but for now
I'd prefer the world where I had a linker that linked .ctf and could be
improved to one where it was forever out of tree because I couldn't
figure out how to do it perfectly. (First improvement coming soon!
dedup :) )
The only argument people have given for stripping it out is not that
it's consuming too much space but that all sections of some type X
must be stripped out no matter what. I'd tend to consider the purpose
of strip(1) to be to save space, so arguments about what sections
should be stripped that do not come down to "this section is too big
and nothing uses it" are not arguments I find terribly convincing,
particularly not when the whole reason for CTF's existence is to try
to make something small enough that it can be used for type
introspection without being so big that people are tempted to strip
it out anyway.
I think you're caught up in a gigantic desktop/server mindset. There
I have several machines with much less space than that. My firewall has
512MiB of flash, total... and yes I want it to have CTF everywhere so I
have a good reason to keep it small!
As Rich said, when people run strip, they really want to get rid of
these sections (outside of loadable segments) that cannot affect program
behaviors.
At least 3 people on this thread have explicitly opposed to make .ctf
survide under strip. This is a pretty strong signal that many people
are against you changing the behavior.
are plenty of systems where even a few hundred kB, much less a few MB,
is way too large to fit in storage for information that is not going
to be used. Introspectability is a niche feature. It's not part of the
C language.
Uh, yeah, that's why -gt is not on by default. There's no point building
CTF into programs that aren't going to use it / aren't part of a suite
that uses it / aren't in an application domain where it would be used
(e.g. my earlier mention of using this in a framework like CORBA or
gobject-introspection: the objects linking it in won't be the users,
it'll be things that want to dlopen() them that will use it).
I was strongly against the choice to make .eh_frame
present by default even in non-debug-mode binaries when it was made,
and I'm likewise against imposing CTF on code that's not intending to
use it.
I'm not planning to do any such thing. There's no point stripping it out
by default because it's not built *in* unless you ask for it, but strip
is usually run by packaging systems without users having any input into
the process (and in particular no ability to pass it arbitrary flags).
Strip this stuff out and you end up unable to use it even if you want
to, because even when you pass -gt the damn thing gets stripped straight
back out again!
I have been here, I have the scars, I'm trying to keep other people from
being scarred in the same way...
It seems likely that making the section loaded might stop people
suggesting that it should be stripped out, by emphasising that "hey,
this is really used". This seems like a bad reason to make that
change, to me, but hey, I guess it *is* another reason. My only
problem with making the thing loaded is practical (I have no idea how
to do it). So, if anyone does have any idea, please do say.
Yes. The structure of the ELF file should reflect the semantics of
what's needed@runtime, so that the tooling can know what
transformations on the file are valid. (Moreover, there should be a
program header or some other way to locate the CTF@runtime via the
loaded content, if it's loaded, rather than having to go back to the
file on disk, which may no longer exist or which may not be
discoverable, e.g. with certain chroot/namespaced configurations,
etc.)
These days (on Linux) you can always look your own text sections'
containing files up via /proc/self/map_files, even in a chroot.
(At least, that worked last time I tried it :) ).
But, as noted, I don't actually *object* to having it be loaded. I
object to being asked to rewrite the linker before submitting a patch
that links .ctf@all, even if not ideally yet. We can always make it
loaded later on if/when we figure out a way to do it that doesn't drive
the developer of the poor thing insane (and the necessary ability, to
have a hierarchy of sections whose contents are allowed to depend on
other sections, with .symtab and .strtab and the compressed debugging
sections etc just being nodes in this graph rather than special cases
everywhere, would be a nice enhancement in general!)
It's not like I'm done submitting improvements to this stuff. :)
--
NULL && (void)