Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/userguide/documentation/command.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ Where [*option...*] is one or more of the following:
--script=file | -T file
--script-options=(match-gnu|match-llvm)
--section-start section=org
--sframe-hdr
-soname=name | -h name
--start-group=archive ... --end-group | -( archive ... -)
--strip-all
Expand Down
14 changes: 13 additions & 1 deletion docs/userguide/documentation/linker_optimizations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,16 @@ Linker Optimization Features

* Note that when building shared libraries, the linker must assume that any visible symbol is referenced.

* If the linker performs a partial link (-r linker option), then you will need to provide the entry point using the -e / --entry linker option.
* If the linker performs a partial link (-r linker option), then you will need to provide the entry point using the -e / --entry linker option.

* SFrame Format Support

* The SFrame (Simple Frame) format provides a lightweight alternative to DWARF debug information for stack unwinding.

* SFrame sections are significantly more compact than equivalent EhFrame sections, reducing binary size and improving runtime performance.

* Use the **--sframe-hdr** option to enable SFrame processing and header creation.

* SFrame data is preserved during garbage collection operations while maintaining consistency with eliminated code.

* More details available at :doc:`sframe_support`
22 changes: 22 additions & 0 deletions docs/userguide/documentation/release_notes.inc
Original file line number Diff line number Diff line change
@@ -1,3 +1,25 @@
===================================
Release notes for Version |release|
===================================

New Features
============

SFrame Support
--------------

ELD now provides comprehensive support for the SFrame (Simple Frame) debugging format:

* **SFrame Version 2 (Errata 1) Support**: Full implementation conforming to the latest SFrame specification for efficient stack unwinding information.

* **Command Line Option**: New ``--sframe-hdr`` option enables processing of ``.sframe`` sections and creation of SFrame headers in output binaries.

* **Multi-Architecture Support**: SFrame functionality available across all supported architectures including AArch64, x86_64, ARM, RISC-V, Hexagon, and MIPS.

* **Performance Optimized**: SFrame sections provide significantly reduced size compared to DWARF debug information while maintaining essential stack unwinding capabilities.

* **Debugger Integration**: Generated SFrame sections are compatible with modern debugging tools including GDB, LLDB, and various profiling utilities.

* **Garbage Collection Aware**: SFrame sections are properly handled during ``--gc-sections`` operations, ensuring consistency between code and unwinding information.

The SFrame format offers substantial benefits for embedded and performance-critical applications where compact debugging information is essential. For detailed usage information, see the SFrame Support documentation.
234 changes: 234 additions & 0 deletions docs/userguide/documentation/sframe_support.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
SFrame Support
==============

.. contents::
:local:

Overview
--------

SFrame (Simple Frame) is a lightweight debugging format that provides stack unwinding information for debuggers and profilers. ELD provides comprehensive support for processing `.sframe` sections and creating SFrame headers in linked executables and shared libraries.

The SFrame format is designed to be much simpler and more compact than DWARF debug information, focusing solely on the minimal information needed for stack unwinding:

* **Canonical Frame Address (CFA)**: The address of the call frame
* **Frame Pointer (FP)**: Location of the frame pointer
* **Return Address (RA)**: Location of the return address

ELD implements support for **SFrame version 2 (errata 1)** as specified in the SFrame Format documentation.

SFrame vs EhFrame
-----------------

SFrame offers several advantages over the traditional EhFrame format:

**Size Efficiency**
SFrame sections are significantly smaller than equivalent EhFrame sections, resulting in reduced binary size and memory usage.

**Parsing Speed**
The simplified format allows for faster parsing during stack unwinding operations.

**Reduced Complexity**
SFrame eliminates much of the complexity of DWARF-based unwinding while maintaining the essential functionality.

**Better Cache Performance**
The compact format leads to better cache utilization during runtime stack unwinding.

Command Line Options
--------------------

ELD provides the following command line option for SFrame support:

``--sframe-hdr``
Create an SFrame header section and process `.sframe` sections in input files. This option enables:

* Processing of `.sframe` sections from input object files
* Creation of consolidated SFrame sections in the output
* Proper linking and address resolution for SFrame data
* Integration with ELD's section layout and memory management

Usage Examples
--------------

Basic Linking with SFrame
~~~~~~~~~~~~~~~~~~~~~~~~~~

To link object files containing `.sframe` sections and create an SFrame header:

.. code-block:: bash

# Create source file with SFrame section
cat > source1.s << 'EOF'
.text
.globl func1
func1:
ret
.section .sframe,"a" # Type automatically set to SHT_GNU_SFRAME (llvm-mc 22.x+)
.byte 0xe2, 0xde, 0x02, 0x08 # SFrame header with magic and version
EOF

# Assemble files containing SFrame sections (requires llvm-mc 22.x or newer)
llvm-mc -filetype=obj -triple=x86_64-linux-gnu source1.s -o source1.o
llvm-mc -filetype=obj -triple=x86_64-linux-gnu source2.s -o source2.o

# Link with SFrame header creation
eld --sframe-hdr source1.o source2.o -o executable

.. note::
For llvm-mc versions prior to 22.x, the section type must be specified explicitly:

.. code-block:: assembly

.section .sframe,"a",@0x6ffffff4 # Explicit SHT_GNU_SFRAME type for older assemblers

Shared Library with SFrame
~~~~~~~~~~~~~~~~~~~~~~~~~~~

SFrame sections can also be included in shared libraries:

.. code-block:: bash

# Create shared library with SFrame information
eld --sframe-hdr -shared libfoo.o -o libfoo.so

Combining with Other Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SFrame support works seamlessly with other ELD features:

.. code-block:: bash

# SFrame with garbage collection
eld --sframe-hdr --gc-sections input.o -o output

# SFrame with optimization
eld --sframe-hdr -O2 input.o -o output

# SFrame with debug symbols
eld --sframe-hdr --debug input.o -o output

Section Processing
------------------

Input Processing
~~~~~~~~~~~~~~~~

ELD processes `.sframe` sections from input object files by:

1. **Recognition**: Identifying `.sframe` sections in ELF input files
2. **Parsing**: Validating SFrame headers and parsing FRE (Frame Row Entry) data
3. **Merging**: Combining multiple `.sframe` sections from different input files
4. **Address Resolution**: Resolving function addresses and updating SFrame data

Output Generation
~~~~~~~~~~~~~~~~~

When the `--sframe-hdr` option is specified, ELD creates:

* **Consolidated .sframe section**: Contains all SFrame data from input files
* **Proper section alignment**: Ensures correct alignment for runtime access
* **Address fixups**: Updates all address references to final linked addresses
* **Section headers**: Creates appropriate ELF section headers for SFrame data

Supported Architectures
-----------------------

ELD's SFrame support is available for the following architectures:

* **AArch64**: Full support for ARM 64-bit architecture
* **x86_64**: Complete x86-64 architecture support
* **ARM**: ARM 32-bit architecture support
* **RISC-V**: RISC-V architecture support
* **Hexagon**: Qualcomm Hexagon DSP architecture support

Each architecture uses the appropriate ABI identifier as specified in the SFrame format specification.

Integration with Debugging Tools
---------------------------------

SFrame sections created by ELD are compatible with:

* **GDB**: GNU Debugger can use SFrame information for stack unwinding
* **LLDB**: LLVM Debugger supports SFrame format
* **Profilers**: Various profiling tools can utilize SFrame data for accurate stack traces
* **Backtrace Libraries**: Runtime libraries can parse SFrame data for stack unwinding

Garbage Collection Behavior
----------------------------

When using `--gc-sections` with SFrame support:

* **Preservation**: SFrame sections are preserved even during aggressive garbage collection
* **Function Tracking**: SFrame entries for garbage-collected functions are removed
* **Consistency**: Remaining SFrame data remains consistent with the final executable
* **No Dangling References**: ELD ensures no SFrame entries reference eliminated code

Error Handling
--------------

ELD provides comprehensive error detection for SFrame processing:

**Invalid Magic Number**
Reports errors for SFrame sections with incorrect magic numbers (expected: 0xdee2)

**Unsupported Version**
Detects and reports unsupported SFrame versions (ELD supports version 2)

**Truncated Sections**
Identifies and reports SFrame sections with incomplete data

**Address Resolution Failures**
Reports errors when SFrame function addresses cannot be resolved

Example error output:

.. code-block:: text

Error: Invalid SFrame magic number in section .sframe from file input.o
Error: Unsupported SFrame version 3 in file input.o (supported: version 2)
Error: SFrame section too small in file input.o

Performance Considerations
--------------------------

SFrame support in ELD is designed for optimal performance:

**Link Time**
* Minimal overhead during linking
* Efficient parsing of SFrame sections
* Fast address resolution and fixups

**Runtime**
* Compact sections reduce memory usage
* Fast parsing during stack unwinding
* Improved cache locality

**Binary Size**
* Significantly smaller than equivalent DWARF information
* Optional inclusion based on build requirements

Best Practices
--------------

1. **Consistent Usage**: Use `--sframe-hdr` consistently across all objects in a project
2. **Testing**: Verify SFrame functionality with debugging tools after linking
3. **Architecture Specific**: Ensure SFrame generation tools target the correct architecture
4. **Integration**: Combine with appropriate optimization levels for best results
5. **Validation**: Use readelf or similar tools to verify SFrame section contents

Troubleshooting
---------------

**Missing SFrame Sections**
Ensure input objects were compiled with SFrame generation enabled

**Incorrect Function Addresses**
Verify that all input objects use consistent compilation flags

**Debugger Issues**
Check that debugging tools support SFrame format version 2

**Performance Problems**
Consider the trade-off between SFrame inclusion and binary size requirements

For additional support and troubleshooting, consult the ELD diagnostic output when using the `--verbose` option along with `--sframe-hdr`.
8 changes: 8 additions & 0 deletions docs/userguide/documentation/target_specific_features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Target Specific Features
.. contents::
:local:

Cross-Platform Features
-----------------------

* **SFrame Support**
The SFrame (Simple Frame) debugging format is supported and tested on x86_64, AArch64, RISCV (both RV32 and RV64), and Hexagon architectures.
See :doc:`sframe_support` for detailed information about SFrame functionality,
usage examples, and integration with debugging tools.


.. ifconfig:: targets in ('Hexagon')

Expand Down
1 change: 1 addition & 0 deletions docs/userguide/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ This document describes usage of ELD
documentation/layout.rst
documentation/linker_plugins_updated.rst
documentation/linker_optimizations.rst
documentation/sframe_support.rst
documentation/getting_image_details.rst
documentation/command.rst

Expand Down
11 changes: 11 additions & 0 deletions include/eld/Config/GeneralOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,15 @@ class GeneralOptions {
bool hasEhFrameHdr() const { return BCreateEhFrameHdr; }
bool isEhFrameHdrSet() const { return BCreateEhFrameHdrSet; }

// --sframe-hdr
void setCreateSFrameHdr(bool PCreateSFrameHdr = true) {
BCreateSFrameHdr = PCreateSFrameHdr;
BCreateSFrameHdrSet = true;
}

bool hasSFrameHdr() const { return BCreateSFrameHdr; }
bool isSFrameHdrSet() const { return BCreateSFrameHdrSet; }

// -n, --nmagic
void setNMagic(bool PMagic = true) { BNMagic = PMagic; }

Expand Down Expand Up @@ -1164,6 +1173,8 @@ class GeneralOptions {
bool BColor = true; // --color[=true,false,auto]
bool BCreateEhFrameHdr = false; // --eh-frame-hdr
bool BCreateEhFrameHdrSet = false;
bool BCreateSFrameHdr = false; // --sframe-hdr
bool BCreateSFrameHdrSet = false;
bool BOMagic = false; // -N, --omagic
bool BNMagic = false; // -n, --nmagic
bool BStripDebug = false; // -S, --strip-debug
Expand Down
12 changes: 11 additions & 1 deletion include/eld/Diagnostics/DiagReaders.inc
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,14 @@ DIAG(error_failed_to_find_driver, DiagnosticEngine::Error,
DIAG(fatal_unsupported_bit_code_file, DiagnosticEngine::Fatal,
"Unsupported architecture %0 in LLVM Bitcode file : %1")
DIAG(note_empty_archive, DiagnosticEngine::Note,
"Empty archive file: '%0'")
"Empty archive file: '%0'")
DIAG(sframe_invalid_magic, DiagnosticEngine::Error,
"Error: Invalid SFrame magic number")
DIAG(sframe_unsupported_version, DiagnosticEngine::Error,
"Error: Unsupported SFrame version")
DIAG(sframe_section_too_small, DiagnosticEngine::Error,
"Error: SFrame section too small")
DIAG(verbose_sframe_reading, DiagnosticEngine::Verbose,
"Reading SFrame section")
DIAG(verbose_sframe_version, DiagnosticEngine::Verbose, "SFrame version %0")
DIAG(verbose_sframe_fres, DiagnosticEngine::Verbose, "SFrame FREs: %0")
4 changes: 4 additions & 0 deletions include/eld/Driver/GnuLinkerOptions.td
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,10 @@ def eh_frame_hdr
: Flag<["--"], "eh-frame-hdr">,
HelpText<"Create EH Frame Header section for faster exception handling">,
Group<grp_optimizationopts>;
def sframe_hdr
: Flag<["--"], "sframe-hdr">,
HelpText<"Create SFrame section for stack unwinding information">,
Group<grp_optimizationopts>;
def no_merge_strings : Flag<["--"], "no-merge-strings">,
HelpText<"Disable String Merging">,
Group<grp_optimizationopts>;
Expand Down
3 changes: 2 additions & 1 deletion include/eld/Fragment/Fragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ class Fragment {
Timing,
Null,
MergeString,
BuildID
BuildID,
SFrame,
};

public:
Expand Down
Loading
Loading