Ran Hong commented: 
https://gitlab.rtems.org/rtems/pkg/rtems-libbsd/-/issues/75#note_144011


I fixed this issue by adding -G0 to the ABI_FLAGS in rtems. 
This is how ABI_FLAGS looks in my config.ini in the rtems source directory (not 
libbsd).

I learned this from Gemini AI. Let me paste what AI said regarding this issue. 
See below:

This error is a specific consequence of how the PowerPC architecture handles 
"Small Data Areas" (SDA) and how modern compilers optimize for memory layout 
using per-variable sections.

To understand why this is happening, we have to look at how the PowerPC ABI 
(Application Binary Interface) tries to save CPU cycles and how the linker 
organizes your binary.
1. The PowerPC SDA (Small Data Area) Optimization

On PowerPC, accessing a standard global variable usually requires two 
instructions because addresses are 32-bit, but a single instruction can only 
carry a 16-bit immediate value.

To optimize this, the PowerPC ABI uses a Small Data Area. The linker groups 
"small" global variables (typically those 8 bytes or smaller) into special 
sections called .sdata or .sbss.

    A register (usually r13 or r2) is initialized to point to the base of this 
area.

    The compiler then uses a R_PPC_SDAREL16 relocation, which allows the CPU to 
access the variable with a single instruction using a 16-bit offset from that 
register.

2. The Conflict: _bsd_vfs_smr in the Wrong Section

The error message tells you exactly what went wrong:

    the target (_bsd_vfs_smr) ... is in the wrong output section (.data)

The compiler generated code for kern_descrip.c assuming that the variable 
_bsd_vfs_smr would be placed in the .sdata section (the Small Data Area). 
However, during the final link, that variable ended up in the standard .data 
section.

Because .data is outside the 16-bit reach of the SDA base register, the 
R_PPC_SDAREL16 relocation "breaks." The linker realizes it cannot calculate a 
16-bit offset to a variable that is sitting far away in the general data 
section.
3. Why "Per-Variable Sections" Cause This

The expert mentioned: "We use per variable/function data/text sections." When 
you compile with flags like -fdata-sections and -ffunction-sections (standard 
in RTEMS to allow the linker to garbage collect unused code), every single 
variable gets its own unique section (e.g., .data._bsd_vfs_smr).

If the linker script or the compiler’s "small data threshold" logic isn't 
perfectly synchronized:

    The Compiler's Guess: While compiling kern_descrip.c, the compiler sees 
_bsd_vfs_smr and thinks, "This is a small variable, I'll use an SDA relocation 
for it."

    The Linker's Reality: At link time, because the variable is in its own 
section (.data._bsd_vfs_smr), the linker might not match it into the .sdata 
output group. It falls back into the general .data group.

4. Why This Happens specifically in RTEMS/libbsd

This often occurs when:

    Threshold Mismatch: One part of the library was compiled with a different 
-G (Small Data Threshold) value than another. If libbsd was compiled with -G 8, 
it assumes anything 8 bytes or smaller is in SDA. If the final application or a 
different object file uses -G 0, they won't agree on where that variable lives.

    External Declarations: _bsd_vfs_smr might be declared in a way that the 
compiler thinks it's small, but the actual definition of the variable is forced 
into a different section by a header or a macro in the FreeBSD kernel code 
ported to RTEMS.

How to Fix It

There are generally three ways to resolve this in an RTEMS environment:

    Uniform Small Data Threshold: Ensure that your application and all linked 
libraries (like libbsd) are compiled with the same -G value. Setting -G 0 
globally is a common (though slightly less performant) way to "turn off" SDA 
and avoid these relocation errors entirely.

    Adjust Linker Scripts: Ensure the linker script explicitly handles the 
per-variable sections by pulling them into the correct SDA output section:
    Code snippet

.sdata : {
    *(.sdata .sdata.* .gnu.linkonce.s.*)
}

Compiler Attributes: If it's just one or two variables, you can use 
__attribute__((section(".data"))) to force the compiler to stop assuming it's 
in the Small Data Area, though this is difficult in a large ported library like 
libbsd.

-- 
View it on GitLab: 
https://gitlab.rtems.org/rtems/pkg/rtems-libbsd/-/issues/75#note_144011
You're receiving this email because of your account on gitlab.rtems.org.


_______________________________________________
bugs mailing list
[email protected]
http://lists.rtems.org/mailman/listinfo/bugs

Reply via email to