Commit graph

8 commits

Author SHA1 Message Date
Jesus Sanchez-Palencia 8ae392e66f x86: Reduce .eh_frame section size
When generating binaries, gcc will always add information of what it
calls "the exception handler framework" into its own section: .eh_frame.
This section is based on the DWARF format's call frame information (CFI) [1]
and holds information that can be useful for debuggers but also for language
constructs that relies on always having stack unwinding information (i.e. exceptions).
Such constructs, however, are pretty much useless for the C language and are
mainly just used on C++. Furthermore, this section is one of the loadable sections
of a binary, meaning it will take extra space on flash.

When .eh_frame is not present, debuggers can still get the exact same information
they need for unwinding a stack frame and for restoring registers thanks to yet
another section: .debug_frame. This section is generated by '-g' gcc option and
friends. It is actually defined by DWARF and, as opposed to .eh_frame, is not a
loadable section. In other words, it is 'strippable' while .eh_frame is not.

Since all we need is the debug information we can get from .debug_frame, we can
disable the generation of these large and unused information tables by using gcc's
'-fno-asynchronous-unwind-tables'. The .eh_frame section stays around but the code
size issue is heavily tackled. This is the same approach taken on other projects
that target small code size generation [2] [3].

Pratically speaking, on a DEBUG build of the all-timers appplication, before this
patch we had:
   text    data     bss     dec     hex filename
  21319    1188   12952   35459    8a83 all-timers.galileo

And now, after this patch:
   text    data     bss     dec     hex filename
  16347    1188   12952   30487    7717 all-timers.galileo

This means a ~5Kb reduction on the loadable text segment (.text + .rodata + .eh_frame).

The flag is applied regardless of build type, DEBUG or RELEASE, since it benefits both.
Note that when release builds apply --gc-sections, they will remove .eh_frame section entirely.

[1] http://comments.gmane.org/gmane.comp.standards.dwarf/222
[2] 0d74ad383b
[3] http://git.musl-libc.org/cgit/musl/commit/?id=b439c051c7eee4eb4b93fc382f993aa6305ce530
[4] https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html

Signed-off-by: Jesus Sanchez-Palencia <jesus.sanchez-palencia@intel.com>
2015-12-21 08:06:14 -02:00
Michael LeMay 0dcd5e9b5a x86: Revise CFLAGS and LDFLAGS for LLVM Clang compatibility
This patch slightly revises CFLAGS and LDFLAGS to specify the
optimization and debugging options and linker script in a way that is
compatible with using Clang as the C compiler and to invoke the linker
(i.e. CC = clang and LD = clang).
2015-12-21 08:06:14 -02:00
Andre Guedes 8a0bc49433 x86: Improve debugging experience
This patch appends some gcc options to CFLAGS when building the default
image in order to improve the debugging experience on GDB.

We use the '-ggdb' option which produces debugging information used by
GDB (including GDB extensions) with level 3 which includes preprocessor
macros information. We also use '-Og' which enables optimizations that
do not interfere with debugging. According to gcc manpage, it should be
the optimization level of choice for the standard edit-compile-debug
cycle, offering a reasonable level of optimization while maintaining
fast compilation and a good debugging experience.

Also, this patch removes the '-g' option from the default CFLAGS because
there is no point in using it when BUILD_RELEASE=1.

As expected, the overall ELF image increases (due to -ggdb3 option) while
the .text section is reduced (due to -Og). For the sake of comparison,
below follows the output of 'size'.

Before patch:
$ size -A hello-world.galileo
hello-world.galileo  :
section           size      addr
.text            13766   1048576
.rodata            241   1064960
.eh_frame         5160   1065204
.eh_frame_hdr     1212   1070364
.data             1188   1073152
.bss             12808   1077248
.debug_info      14351         0
.debug_abbrev     6281         0
.debug_aranges     768         0
.debug_line       6443         0
.debug_str        4805         0
.comment            17         0
.note               40         0
.debug_ranges       24         0
Total            67104

After patch:
$ size -A hello-world.galileo
hello-world.galileo  :
section            size      addr
.text             11718   1048576
.rodata             249   1060864
.eh_frame          5496   1061116
.eh_frame_hdr      1204   1066612
.data              1156   1069056
.bss              12808   1073152
.debug_info       16727         0
.debug_abbrev      7254         0
.debug_loc         2083         0
.debug_aranges      768         0
.debug_macro      17273         0
.debug_line       13433         0
.debug_str        42192         0
.comment             17         0
.note                40         0
Total            132418
2015-12-21 08:06:14 -02:00
Andre Guedes c9020d95e7 x86: Build release image
This patch adds support for building release images. The main difference
between release images and default images is that the former is optimized
for size while the latter is "optimized" for debugging. To build a release
image, the BUILD_RELEASE variable should be set to 1. For instance, the
following command build a release image from the hello-world application:
$ cd examples/hello-world && make TARGET=galileo BUILD_RELEASE=1

To optimize for size we use the '-Os' option from gcc. This option also
enables the strict aliasing optimization. This generates lots of warning
messages since we use the '-Wall' option and lots of code in core/net/
break the strict-aliasing rules. Some test have shown that the strict
aliasing optimization it not taking effect in the final binary. For that
reasons, this patch manually disables the optimization. Also, the release
image is stripped.

For the sake of comparison, below follows the output from 'wc' and 'size'
for both debugging (default) and release images.

Default image:
$  wc -c hello-world.galileo
71112 hello-world.galileo
$ size hello-world.galileo
   text    data     bss     dec     hex filename
  20379    1188   12808   34375    8647 hello-world.galileo

Release image:
$ wc -c hello-world.galileo
26320 hello-world.galileo
$ size hello-world.galileo
   text    data     bss     dec     hex filename
  18146    1156   12808   32110    7d6e hello-world.galileo
2015-12-21 08:06:14 -02:00
Andre Guedes b697646b11 x86: Cleanup Makefile.x86_common
This patch does several cleanups in Makefile.x86_common file. The
changes are described above.

1) The CFLAGNO variable was removed since it is used only to assign
   the CFLAGS variable. Also, CFLAGNO is not used outside Makefile.x86_
   common.

2) The "-I/usr/local/include" option was removed since we provide manually
   the include path from newlib in the bsp/ directory.

3) We only support building x86-based platforms on Linux so there is no
   point in setting LDFLAGS conditionally.

4) The '-export-dynamic' option was removed from LDFLAGS since we are not
    creating a dynamically linked executable.

5) Makefile.x86_quarkX1000 is the only one that includes Makefile.x86_
   common. Since it doesn't use the custom rules from Makefile.x86_
   common we remove them.
2015-12-21 08:06:14 -02:00
Andre Guedes 13bbe8a5b5 x86: Don't generate .note.gnu.build-id section
This patch adds "--build-id=none" to default LDFLAGS so
.note.gnu.build-id section is not generated. This section
contains unique identification for the built files what is
not important to us (at least at this moment).

This change simplifies all linker scripts for SoCs based on x86
(at this moment we only have Quark X1000) since we don't have to
care about it anymore.
2015-12-21 08:06:14 -02:00
Jesus Sanchez-Palencia e4bc1a1e8c x86: Add init folder and move code accordingly
The x86/init/common/ folder holds all cpu initialization
code - idt and gdt setup, interrupts and cpu initialization.

On this folder will also sit any SoC specific implementation of
the functions called from cpu_init().
2015-12-21 08:06:14 -02:00
Jesus Sanchez-Palencia b2fa72bb98 x86: Break Makefile.x86 into common and pc specific ones
Now the cpu/x86/ provides a Makefile.x86_common and a
Makefile.x86_pc. The former includes the common Makefile
and adds legacy pc specific implementations (currently,
drivers only) into the building context, while the latter
has everything that defines the bootstrap of a x86 CPU.

This commit also fixes platform/galileo/ so it includes the
correct makefile - Makefile.x86_quarkX1000. Galileo uses
a Quark X1000 SoC which is not an IBM Generic PC-like CPU,
but it does provide most of a PCs peripherals through
its "Legacy Bridge". Thus, it makes sense that QuarkX1000's
Makefile includes code from the legacy_pc x86 cpu.
2015-12-21 08:06:14 -02:00
Renamed from cpu/x86/Makefile.x86 (Browse further)