devkitPro / libgba

C Library for Nintendo GBA
http://devkitpro.org/viewforum.php?f=5
Other
192 stars 26 forks source link

gba_base.h: fix "section conflict" GCC error #9

Closed LunarLambda closed 10 months ago

LunarLambda commented 3 years ago

When mixing IWRAM_CODE and IWRAM_DATA in the same file, GCC generates a "section type conflict" error:

#include <gba_console.h>
#include <gba_video.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
#include <stdlib.h>

void IWRAM_CODE hello(void)
{
    iprintf("Hello, world!\n");
}

int IWRAM_DATA x = 1;

int main(void)
{
    irqInit();
    irqEnable(IRQ_VBLANK);

    consoleDemoInit();

    hello();
    iprintf("%i\n", x);

    while (1)
    {
        VBlankIntrWait();
    }
}
src/main.c: In function 'main':
src/main.c:14:16: error: 'x' causes a section type conflict with 'hello'
   14 | int IWRAM_DATA x = 1;
      |                ^
src/main.c:9:17: note: 'hello' was declared here
    9 | void IWRAM_CODE hello(void)
      |                 ^~~~~

This is quickly fixed making IWRAM_DATA (and EWRAM_DATA) map to a different section, .iwram_data (.ewram_data) instead.

The linker script handles this fine due to wildcard matching.

maraflush commented 2 years ago

Hello,

I'm 100% sure but the __attribute__, here IWRAM_CODE and IWRAM_DATA should be before the type.

IWRAM_CODE void hello(void)
{
    iprintf("Hello, world!\n");
}
IWRAM_DATA int x = 1;

Regards,

LunarLambda commented 2 years ago

It makes absolutely zero difference, and in fact GCC generally recommends putting attributes before identifiers, not types.

I would highly appreciate if people actually tested their claims before making them, such that I'm not required to waste my time disproving them.

#include <gba_console.h>
#include <gba_video.h>
#include <gba_interrupt.h>
#include <gba_systemcalls.h>
#include <gba_input.h>
#include <stdio.h>
#include <stdlib.h>

IWRAM_CODE void hello(void)
{
    iprintf("Hello, world!\n");
}

IWRAM_DATA int x = 1;

int main(void)
{
    irqInit();
    irqEnable(IRQ_VBLANK);

    consoleDemoInit();

    hello();
    iprintf("%d\n", x);

    while (1)
    {
        VBlankIntrWait();
    }
}
src/main.c: In function 'main':
src/main.c:14:16: error: 'x' causes a section type conflict with 'hello'
   15 | IWRAM_DATA int x = 1;
      |                ^
src/main.c:9:17: note: 'hello' was declared here
   10 | IWRAM_CODE void hello(void)
      |                 ^~~~~
maraflush commented 2 years ago

Thank you for your check. May be a nds_examples (in devkitpro) exists for this own ?

LunarLambda commented 2 years ago

What? libgba has nothing to do with the NDS. This is just a matter of libgba's attribute macros being broken.

maraflush commented 2 years ago

What? libgba has nothing to do with the NDS. This is just a matter of libgba's attribute macros being broken.

The architecture of NDS and GBA are quite similar. Moreover the NDS is retro-compatible with GBA. (maybe some linkscripts/headers/code can be bug fixed).

If you want to dive into the devkitpro mechanics under the hood (gba) , look :

LunarLambda commented 2 years ago

I am well familiar with the linker scripts. This has nothing to do with that, the error happens at the compiler level, because the compiler does not permit creating sections that are both writable and executable.

(maybe some linkscripts/headers/code can be bug fixed).

The entire purpose of this PR is to fix the headers by making the macros work such that section conflicts will not happen under normal use.

maraflush commented 2 years ago

Oh ok ! :) Thank you for your answer which enrich my understanding. 👍

WinterMute commented 10 months ago

Sorry to leave this sitting so long. Forgotten in the midst of other things. Merged manually