gcc can place code into the .rodata section. I found this while debugging a
crash in Ingo Molnar's sched-devel kernel. In the kernel code
arch/x86/kernel/alternative.c the static inline function costant_test_bit was
placed into the rodata. Later on in the kernel boot up sequence, the rodata
section is protected with the NX bit in the page tables. The next time the code
in the rodata is executed we get a crash.

I'll attach a file that shows this behaviour. I tried to strip it down but too
many modifications to the file makes the issue disappear. I compiled the code
with the -E option and saved that file to get rid of any header information
that would prevent you from seeing the issue.

I have also trimmed down the arguments that I pass in to :

[EMAIL PROTECTED]:~/gcc$ gcc -fno-strict-aliasing -Os -m64 -funit-at-a-time  -g
-c -o alt.o alt.c 
[EMAIL PROTECTED]:~/gcc$ nm alt.o | grep constant_test_bit
0000000000000090 r constant_test_bit
[EMAIL PROTECTED]:~/gcc$ gcc -v                         
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc-4.2.2/configure --prefix=/usr/local/dist
--program-prefix=dist- --without-doc --enable-bootstrap --enable-64-bit-bfd
Thread model: posix
gcc version 4.2.2


I've compiled this version of gcc myself, but I have also seen this issue in
the  Red Hat Enterprise Linux version of gcc: 

[EMAIL PROTECTED] linux-x86-sched-devel.git]# gcc -v
Using built-in specs.
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man
--infodir=/usr/share/info --enable-shared --enable-threads=posix
--enable-checking=release --with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-libgcj-multifile
--enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk
--disable-dssi --enable-plugin
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic
--host=x86_64-redhat-linux
Thread model: posix
gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)


Also note that the call is in fact to the .rodata as seen with:

objdump -Dra alt.o :

  8e:   e8 00 00 00 00          callq  93 <alternatives_smp_module_add+0x30>
                        8f: R_X86_64_PC32       .rodata+0x8c

Disassembly of section .rodata:
[...]
0000000000000090 <constant_test_bit>:
  90:   89 f9                   mov    %edi,%ecx
  92:   bf 40 00 00 00          mov    $0x40,%edi
  97:   89 c8                   mov    %ecx,%eax
  99:   99                      cltd   
  9a:   f7 ff                   idiv   %edi
  9c:   89 d1                   mov    %edx,%ecx
  9e:   48 63 d0                movslq %eax,%rdx
  a1:   48 8b 04 d6             mov    (%rsi,%rdx,8),%rax
  a5:   48 d3 e8                shr    %cl,%rax
  a8:   83 e0 01                and    $0x1,%eax
  ab:   c3                      retq   
  ac:   00 00                   add    %al,(%rax)


-- 
           Summary: gcc puts code in rodata section with -Os -g -funit-at-a-
                    time
           Product: gcc
           Version: 4.2.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rostedt at goodmis dot org
 GCC build triplet: x86_64-unknown-linux-gnu
  GCC host triplet: x86_64-unknown-linux-gnu
GCC target triplet: x86_64-unknown-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35895

Reply via email to