tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Binutils 2.39 on -CURRENT: Seemingly bogus warnings about .note.GNU-stack
Hi,
-CURRNET has Binutils 2.39 which introduces new warnings about
.note.GNU-stack section [1]. It's a GNU extension in the ELF header to
ask the kernel to mark the stack pages executable or not. However, stack
on NetBSD is always non-executable and our kernel just ignores it (which
is fine).
It appears that recent versions of GCC emit .note.GNU-stack on Linux but
don't on NetBSD (which is also fine), and BFD ld gladly produces
executables without PT_GNU_STACK when every object file lacks
.note.GNU-stack section.
Things get interesting when some of object files to be linked together
have .note.GNU-stack but others don't. In this case Binutils 2.39 emits
the following warning and marks the resulting object as "stack needs to
be executable":
ld: warning: foo.o: missing .note.GNU-stack section implies
executable stack
ld: NOTE: This behaviour is deprecated and will be removed in a
future version of the linker
I believe this doesn't make sense on NetBSD, where stack is never
executable. Binutils has a configure-time option
"--enable-warn-execstack=no" to disable this, and I think we should use
this option. But (1) I don't know how configure scripts are executed in
base, and (2) I'd like to hear how other people think. Here's a test case:
https://gist.github.com/depressed-pho/2d379beb39759d810c93d19dda42eede
[1]
https://www.redhat.com/en/blog/linkers-warnings-about-executable-stacks-and-segments
# The reason why I stumbled on this (TL;DR)
I'm in the process of porting GHC, The Glasgow Haskell Compiler 9.4 to
pkgsrc. GHC usually compiles Haskell source files directly to asm and
invokes as(1) and cc(1) to assemble and link them. In the configuration
phase (./configure) it checks if the toolchain supports .note.GNU-stack,
and if so it emits the following section saying "I don't need the stack
to be executable" for all the assembly sources it produces:
.section .note.GNU-stack,"",@progbits
This is because GHC never requires executable stack. However, there is a
case where GHC needs to generate some C source and ask cc(1) to compile
it. In Haskell you can declare a C function and treat it as if it were a
regular Haskell function like so:
foreign import capi "stdlib.h putenv" ::
c_putenv :: CString -> IO CInt
This tells the compiler to find a C function putenv() in a C header
<stdlib.h>, and treat it as a Haskell function of type CString -> IO
CInt. When GHC sees this, it produces something equivalent to the
following C source:
#include <stdlib.h>
int c_putenv_wrapper(char* arg0) {
return putenv(arg0);
}
The reason why it needs to do this, is that the imported C function
(putenv(3) in this case) might not be an actual symbol but can in fact
be a CPP macro. GHC then invokes cc(1) to compile it into a .o file, and
uses "ld -r" to merge it with the main Haskell object file.
But since GCC doesn't emit .note.GNU-stack for this auxiliary object
while GHC does for the main object, Binutils 2.39 complains about this
and marks the merged object as requiring executable stack. The resulting
object file will then be linked together with other objects, and again
ld(1) emits a warning while producing the final executable. This happens
basically every time GHC is invoked and is a major source of noise.
While I can probably patch GHC to not bother with .note.GNU-stack, the
whole mess Binutils created is worth sorting out IMO.
Home |
Main Index |
Thread Index |
Old Index