Skip to content

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

Closed
LunarLambda wants to merge 1 commit intodevkitPro:masterfrom
LunarLambda:patch-fix-section-conflict
Closed

gba_base.h: fix "section conflict" GCC error#9
LunarLambda wants to merge 1 commit intodevkitPro:masterfrom
LunarLambda:patch-fix-section-conflict

Conversation

@LunarLambda
Copy link
Contributor

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.

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

```c
#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();
    }
}
```

```
/home/luna/dev/homebrew/gba/iwram-test/src/main.c: In function 'main':
/home/luna/dev/homebrew/gba/iwram-test/src/main.c:14:16: error: 'x' causes a section type conflict with 'hello'
   14 | int IWRAM_DATA x = 1;
      |                ^
/home/luna/dev/homebrew/gba/iwram-test/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
Copy link
Contributor

maraflush commented Dec 27, 2021

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
Copy link
Contributor Author

LunarLambda commented Dec 27, 2021

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
Copy link
Contributor

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

@LunarLambda
Copy link
Contributor Author

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

@maraflush
Copy link
Contributor

maraflush commented Dec 27, 2021

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
Copy link
Contributor Author

LunarLambda commented Dec 27, 2021

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
Copy link
Contributor

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

LunarLambda added a commit to gbadev-org/libgba that referenced this pull request Nov 13, 2022
Make the *_CODE and *_DATA section macros use separate section names.
This fixes GCC complaining about conflicting section permissions
(R-X vs RW-) when IWRAM_CODE and IWRAM_DATA are used in the same file.
See devkitPro/libgba#9 for more information.
@WinterMute
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants