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