Libgcc without red zone: Difference between revisions

m
Bot: Replace deprecated source tag with syntaxhighlight
[unchecked revision][unchecked revision]
mNo edit summary
m (Bot: Replace deprecated source tag with syntaxhighlight)
 
Line 14:
 
To get around this the <tt>red-zone</tt> can be disabled by passing <tt>-mno-red-zone</tt> to [[GCC]].
<sourcesyntaxhighlight lang="bash">x86_64-elf-gcc $CFLAGS -mno-red-zone ...</sourcesyntaxhighlight>
 
== Why modify libgcc? ==
Line 28:
 
Create the following file and save it as <tt>t-x86_64-elf</tt> inside <i><tt>gcc/config/i386/</tt></i> under your [[GCC]] sources.
<sourcesyntaxhighlight lang="Make">
# Add libgcc multilib variant without red-zone requirement
 
MULTILIB_OPTIONS += mno-red-zone
MULTILIB_DIRNAMES += no-red-zone
</syntaxhighlight>
</source>
 
By default this new configuration will not be used by [[GCC]] unless it's explicitly told to.
Open <tt>gcc/config.gcc</tt> in your favorite editor and search for case block like this:
<sourcesyntaxhighlight lang="bash">
x86_64-*-elf*)
tm_file="${tm_file} i386/unix.h i386/att.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h"
;;
</syntaxhighlight>
</source>
 
This is the target configuration used when creating a [[GCC Cross-Compiler]] for x86_64-elf.
Modify it to include the new [[multilib]] configuration:
<sourcesyntaxhighlight lang="bash">
x86_64-*-elf*)
tmake_file="${tmake_file} i386/t-x86_64-elf" # include the new multilib configuration
tm_file="${tm_file} i386/unix.h i386/att.h elfos.h newlib-stdint.h i386/i386elf.h i386/x86-64.h"
;;
</syntaxhighlight>
</source>
 
== Building libgcc ==
Line 56:
Run configure and then invoke the <tt>all-target-libgcc</tt> and <tt>install-target-libgcc</tt> as usual and [[GCC]] will build [[libgcc]] in two versions - one with <tt>red-zone</tt> enabled and one without.
You can check the successful build by checking the installed <tt>libgcc.a</tt> archives:
<sourcesyntaxhighlight lang="bash">
find $TOOLCHAIN_PREFIX/lib -name 'libgcc.a'
</syntaxhighlight>
</source>
 
If all went well you should see an additional [[libgcc]] installed in the <tt>no-red-zone</tt> multilib directory:
<sourcesyntaxhighlight lang="text">
./gcc/x86_64-pc-elf/4.9.1/libgcc.a
./gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a
</syntaxhighlight>
</source>
 
== Linking against the correct multilib version ==
Assuming you're using [[GCC]] to link your kernel you're probably fine. All that's needed is to make sure <tt>-mno-red-zone</tt> is in your <tt>LDFLAGS</tt> when doing the final linker call.
<sourcesyntaxhighlight lang="bash">
x86_64-elf-gcc $LDFLAGS -mno-red-zone -o kernel $SOURCES
</syntaxhighlight>
</source>
 
If you're unsure which [[libgcc]] version is going to be used you can check by passing <tt>-mno-red-zone</tt> and <tt>-print-libgcc-file-name</tt> to [[GCC]]:
<sourcesyntaxhighlight lang="bash">
x86_64-elf-gcc -mno-red-zone -print-libgcc-file-name
lib/gcc/x86_64-pc-elf/4.9.1/no-red-zone/libgcc.a
</syntaxhighlight>
</source>
 
==See Also==