2

I'm working on a big embedded project and I'm facing an issue that I cannot explain with my limited knowledge of linkers. I've managed to recreate the problem in a really simple program.

I have a single C source file and I want to align an array to a 16 kB boundary, but I don't want to do that with the aligned attribute. Instead, I want to use ALIGN builtin function of the linker script.

The source file is pretty simple:

#include "boot.h"

typedef unsigned char uint8_t;

uint8_t boo[0x800] __attribute__ (( section(".data_aligned") )) = { 0U };

uint8_t foo[0x800] = { 1U };

void start()
{
    return;
}

And the linker script is:

SECTIONS
{
    . = 0x00100000 ;

    _sCode = . ;

    .text ALIGN(0x1000) : { *(.text) }

    .data ALIGN(0x1000) :
    {
        _sData = . ;
        *(.data) ;
        _eData = . ;
        . = ALIGN(0x4000) ;
        _sDataAlign = . ;
        *(.data_aligned) ;
        _eDataAlign = . ;
    }

    .rodata ALIGN(0x1000) : { *(.rodata) }
    
    .bss ALIGN(0x1000) : { *(.bss) }
    
    _eCode = . ;
    
}

I compiled and linked the project with gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) with these commands:

gcc -c -masm=att -m32 -nostdinc -nostdlib -fno-builtin -fno-pic -std=c99 -o bin/boot.o boot.c
ld -e 0x100000 bin/boot.o -T linker_script_gcc.ld -m elf_i386 --verbose -O0 -o bin/application.elf

From the elf file I get:

     ...
     8: 00101000     0 NOTYPE  GLOBAL DEFAULT    2 _sData
     2: 00101000     0 SECTION LOCAL  DEFAULT    2 
    13: 00101000  2048 OBJECT  GLOBAL DEFAULT    2 foo
    10: 00101800     0 NOTYPE  GLOBAL DEFAULT    2 _eData
    14: 00104000     0 NOTYPE  GLOBAL DEFAULT    2 _sDataAlign
     7: 00104000  2048 OBJECT  GLOBAL DEFAULT    2 boo
     9: 00104800     0 NOTYPE  GLOBAL DEFAULT    2 _eDataAlign
    ...

It seems that the boo array has been succesfully aligned to the 16 kB boundary.

However, when this program is compiled with the GHS compiler, the boo array is not aligned as expected:

    ...
    26: 00101000     0 NOTYPE  GLOBAL DEFAULT    2 _sData
     6: 00101000 18432 SECTION LOCAL  DEFAULT    2 .data
    22: 00101000  2048 OBJECT  GLOBAL DEFAULT    2 foo
    27: 00101800     0 NOTYPE  GLOBAL DEFAULT    2 _eData
    28: 00105000     0 NOTYPE  GLOBAL DEFAULT    2 _sDataAlign
    21: 00105000  2048 OBJECT  GLOBAL DEFAULT    2 boo
    29: 00105800     0 NOTYPE  GLOBAL DEFAULT    2 _eDataAlign
    ...

So I wondered what really should be the value of _sDataAlign and why.

According to the documentation linked here, the location counter in a linker script is relative to the start of the output section in which is evaluated:

Note: . actually refers to the byte offset from the start of the current containing object. Normally this is the SECTIONS statement, whose start address is 0, hence . can be used as an absolute address. If . is used inside a section description however, it refers to the byte offset from the start of that section, not an absolute address.

Moreover, here it is explained:

Unary operations on a relative address, and binary operations on two relative addresses in the same section or between one relative address and a number, apply the operator to the offset part of the address(es).

And:

The result of other operations on relative addresses (after above conversions) is a relative address in the same section as the operand(s).

So, in my understanding, the symbol _sDataAlign is set to 0x4000 relative to the start of the .data section which is 0x101000. Therefore, _sDataAlign should be 0x105000, exactly as computed by the GHS compiler.

Is this analysis correct? If so, why GNU linker is giving me a wrong value?

4
  • 4
    Does your GHS actually support the __attribute__(()) stuff? This was introduced by GCC and then taken by CLANG, but not all compilers might support that. Commented Jul 17, 2023 at 1:19
  • Yes, according to the manual, my GHS supports the attribute keyword and specifically it supports the section attribute. Indeed, the boo array is correctly placed after the _sDataAlign symbol where the section .data_aligned is placed. Commented Jul 17, 2023 at 9:10
  • BTW, if you have problems with the GHS, why are you pasting here excerpts from the GNU linker and not the one from the GHS linker? Commented Jul 23, 2023 at 22:50
  • Because, after my analysis explained in the question, I definitely agree with the value calculated by the GHS linker and NOT with the one calculated by the GNU linker... Commented Jul 23, 2023 at 23:20

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.