public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* ld: provide /PASSTHRU/ section rule to avoid orphan warnings?
@ 2023-08-29 20:39 Kees Cook
  2023-09-04 12:12 ` Nick Clifton
  0 siblings, 1 reply; 4+ messages in thread
From: Kees Cook @ 2023-08-29 20:39 UTC (permalink / raw)
  To: binutils; +Cc: maskray

Hi!

The Linux kernel would like to have a way for the linker to emit sections
without changing their section name, using wildcards. (This is needed
for our efforts towards Function-Granular Kernel Address Space Layout
Randomization[1].) Normally this happens automatically if a section
doesn't match an existing rule, but then the --orphan-handling=warn
option will report it. There is currently no way to silence these
"expected sections".

e.g. if we had something like:

	/PASSTHRU/ : {
		*(.text.*)
	}

Then stuff like ".text.func1" and ".text.func2" will pass through as-is,
but something unexpected, like ".other" would still get correctly
reported by --orphan-handling=warn.

I've opened issues in both binutils[2] and LLVM[3] for this and was
hoping to get some feedback on what's needed to see this implemented.  :)

Thanks!

-Kees

[1] https://github.com/KSPP/linux/issues/132
[2] https://sourceware.org/bugzilla/show_bug.cgi?id=28772
[3] https://github.com/llvm/llvm-project/issues/65087

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ld: provide /PASSTHRU/ section rule to avoid orphan warnings?
  2023-08-29 20:39 ld: provide /PASSTHRU/ section rule to avoid orphan warnings? Kees Cook
@ 2023-09-04 12:12 ` Nick Clifton
  2023-10-11 17:23   ` Kees Cook
  0 siblings, 1 reply; 4+ messages in thread
From: Nick Clifton @ 2023-09-04 12:12 UTC (permalink / raw)
  To: Kees Cook, binutils; +Cc: maskray

Hi Kees,

> The Linux kernel would like to have a way for the linker to emit sections
> without changing their section name, using wildcards.

I take it that it is hard/impossible for the kernel build process to know
beforehand what these section names will be ?  If the build process did
know then it could probably use a linker script fragment to ensure that
they were copied through.


> Normally this happens automatically if a section
> doesn't match an existing rule, but then the --orphan-handling=warn
> option will report it. There is currently no way to silence these
> "expected sections".

So one way to address this problem would be to extend the --orphan-handling
option so that it does not emit messages for certain sections.  This has the
advantage of not needing to extend the linker script syntax.  How about
something like --no-warn-orphan=<wildcard> option which could suppress warnings
for matching sections ?  Or --orphan-handling=warn-except-text which would
warn for any unplaced section that is not executable ?


> e.g. if we had something like:
> 
> 	/PASSTHRU/ : {
> 		*(.text.*)
> 	}
> 
> Then stuff like ".text.func1" and ".text.func2" will pass through as-is,
> but something unexpected, like ".other" would still get correctly
> reported by --orphan-handling=warn.

I have a feeling that this solution would be difficult to implement since the
linker script processing is not really set up for generating an unknown number
of output sections from a single clause in the script.  I am not 100% sure of
this though, since I have not actually tried to implement it.

In theory the script extension seems like a good idea, although I do wonder
about section ordering.  For example, suppose a script had this:

   /PASSTHRU/ : { *(.text.*) *(.init.*) }

and then you have two input files - a.o containing .text.a.foo and .init.a.foo
and b.o containing .text.b.foo and .init.b.foo.  In the resulting output, what
order should the sections appear ?

   .text.a.foo
   .init.a.foo
   .text.b.foo
   .init.b.foo

(assuming that a.o comes before b.o on the linker command line) or:

   .text.a.foo
   .text.b.foo
   .init.a.foo
   .init.b.foo

(because the .text.* pattern appears before the .init.* pattern in the linker script)

Or maybe no ordering should be expected and the user gets whatever the linker
decides to do.


Obviously it would be best if LLD and LD.BFD and LD.GOLD all supported the
same solution, so lets see if we can coordinate our response.

Cheers
   Nick


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: ld: provide /PASSTHRU/ section rule to avoid orphan warnings?
  2023-09-04 12:12 ` Nick Clifton
@ 2023-10-11 17:23   ` Kees Cook
  0 siblings, 0 replies; 4+ messages in thread
From: Kees Cook @ 2023-10-11 17:23 UTC (permalink / raw)
  To: Nick Clifton; +Cc: binutils, maskray

On Mon, Sep 04, 2023 at 01:12:18PM +0100, Nick Clifton wrote:
> Hi Kees,

Hi! Thanks for the looking at this and sorry I got distracted until now
to reply to this. :)

> > The Linux kernel would like to have a way for the linker to emit sections
> > without changing their section name, using wildcards.
> 
> I take it that it is hard/impossible for the kernel build process to know
> beforehand what these section names will be ?  If the build process did
> know then it could probably use a linker script fragment to ensure that
> they were copied through.

It's certainly possible, but it's "extra work" that really doesn't seems
to be done in the right place. "Make a list of all section names that
are in the files that the linker is about to read where it finds the
same list." :)

More specifically, when this is done, we end up with a 65,000 line linker
script, and the link stage (which normally takes a handful of seconds)
ends up taking something like 10 minutes -- I assume the linker is doing
repeated linear searches. So while that pathological condition could
certainly be found it illustrates to me that listing all sections
explicitly is going down the wrong solution path.

> > Normally this happens automatically if a section
> > doesn't match an existing rule, but then the --orphan-handling=warn
> > option will report it. There is currently no way to silence these
> > "expected sections".
> 
> So one way to address this problem would be to extend the --orphan-handling
> option so that it does not emit messages for certain sections.  This has the
> advantage of not needing to extend the linker script syntax.  How about
> something like --no-warn-orphan=<wildcard> option which could suppress warnings
> for matching sections ?  Or --orphan-handling=warn-except-text which would
> warn for any unplaced section that is not executable ?

Yeah, that could work, for sure. My instinct is that this would become
ungainly over time, though, since we'd now be splitting section naming
logic between the linker script and the command-line invocation, which
we've never had to do before: all the section name patterns we're
dealing with are only in the linker script right now. And as we start
adding more than just .text.* to the pass-through list, we'll end up
having to make the linker invocation more and more complex.

Right now all of the section patterns are built with various macros and
conditions in the linker script. Having to bring that out into the
invocation seems like poor ergonomics.

> > e.g. if we had something like:
> > 
> > 	/PASSTHRU/ : {
> > 		*(.text.*)
> > 	}
> > 
> > Then stuff like ".text.func1" and ".text.func2" will pass through as-is,
> > but something unexpected, like ".other" would still get correctly
> > reported by --orphan-handling=warn.
> 
> I have a feeling that this solution would be difficult to implement since the
> linker script processing is not really set up for generating an unknown number
> of output sections from a single clause in the script.  I am not 100% sure of
> this though, since I have not actually tried to implement it.

I assumed that it wouldn't be too hard since the orphan handling already
does what we want: it just copies an input section to an identically
named output section. I figured the patterns loaded from a "/PASSTHRU/"
list would just be used to silence the orphan warning.

> In theory the script extension seems like a good idea, although I do wonder
> about section ordering.  For example, suppose a script had this:
> 
>   /PASSTHRU/ : { *(.text.*) *(.init.*) }
> 
> and then you have two input files - a.o containing .text.a.foo and .init.a.foo
> and b.o containing .text.b.foo and .init.b.foo.  In the resulting output, what
> order should the sections appear ?
> 
>   .text.a.foo
>   .init.a.foo
>   .text.b.foo
>   .init.b.foo
> 
> (assuming that a.o comes before b.o on the linker command line) or:
> 
>   .text.a.foo
>   .text.b.foo
>   .init.a.foo
>   .init.b.foo
> 
> (because the .text.* pattern appears before the .init.* pattern in the linker script)
> 
> Or maybe no ordering should be expected and the user gets whatever the linker
> decides to do.

Right -- I think the ordering is just whatever order the linker
encounters the sections. The orphan handling appears to do this already
(though it does seem to attempt to "group" similar stuff, but that's
heuristic we don't depend on at all).

Our use of /PASSTHRU/ very much doesn't care about ordering since we're
literally going to randomize the order of those sections at load time
anyway. :) But yes, I see why you'd want some kind of declaration of
intended behavior.

> Obviously it would be best if LLD and LD.BFD and LD.GOLD all supported the
> same solution, so lets see if we can coordinate our response.

Agreed! It was Fangrui Song who suggested I make sure LD.BFD was
involved in the discussion, as I originally had just asked about LLD.
(I'd wanted to gauge how difficult this feature would be.)

So, as a strawman, how about this:

- When warning about orphan sections, anything matching a /PASSTHRU/
  rule is silenced (as it is now an 'expected' pass-through.
- Therefore for ordering purposes the /PASSTHRU/ section behaves like
  it is "last" in the linker script, regardless of its actual position.

-- 
Kees Cook

^ permalink raw reply	[flat|nested] 4+ messages in thread

* ld: provide /PASSTHRU/ section rule to avoid orphan warnings?
@ 2024-03-08  8:24 Bevin Hansson
  0 siblings, 0 replies; 4+ messages in thread
From: Bevin Hansson @ 2024-03-08  8:24 UTC (permalink / raw)
  To: binutils; +Cc: nickc, keescook

Hi,

We also have a need for a feature like this in lld. There doesn't seem to be
much more activity on this, so I'll offer my two cents on the topic.

> So one way to address this problem would be to extend the --orphan-handling
> option so that it does not emit messages for certain sections.  This has the
> advantage of not needing to extend the linker script syntax.  How about
> something like --no-warn-orphan=<wildcard> option which could suppress warnings
> for matching sections ?  Or --orphan-handling=warn-except-text which would
> warn for any unplaced section that is not executable ?

I think that the wildcard flag idea would cover our use case; not the more
specific option, though. However, I think that having the linker script feature
is a lot more flexible. It lets you express that sections in certain files
should be preserved, but later match everything of that section:

    /PASSTHRU/ : {
      foo.o(.bar.x);
    }

    .bar : {
      *(.bar*);
    }

This would prevent the matching of the .bar.x section from that particular
file (since it has already been matched by the /PASSTHRU/), but would still
allow you to globally match anything with that prefix afterwards. This wouldn't
be possible with the option approach, since it would only take effect at the
end after all of the matching is already done.

However, this isn't the same behavior as what Kees' mentioned:
> - Therefore for ordering purposes the /PASSTHRU/ section behaves like
>   it is "last" in the linker script, regardless of its actual position.

But maybe this is simpler to implement in ld than in lld? For the time being I
can't really see my above example as a use case for us specifically, but the
need might pop up in the future. I think it's a bit odd to have it in the
linker script and then not have it behave as other 'special' output sections
do, like /DISCARD/. That wouldn't be what I'd expect as a user.

Regardless, I do agree with Kees' point that having this kind of logic in
the linker invocation rather than the linker script is a bit cumbersome.

> Or maybe no ordering should be expected and the user gets whatever the linker
> decides to do.

I think this is the reasonable behavior. The order of matches in the block
shouldn't matter in the same way that the order doesn't matter in a /DISCARD/
block.

/ Bevin

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-03-08  8:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-29 20:39 ld: provide /PASSTHRU/ section rule to avoid orphan warnings? Kees Cook
2023-09-04 12:12 ` Nick Clifton
2023-10-11 17:23   ` Kees Cook
2024-03-08  8:24 Bevin Hansson

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).