cc65 / cc65

cc65 - a freeware C compiler for 6502 based systems

Home Page:https://cc65.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

data goes into the wrong section/segment when segment is changed more than once

mrdudz opened this issue · comments

Sorry for odd description :) I am just done bisecting.... 20c3e99 is the first non working commit.

It breaks so odd and weird, i have no idea what i am even looking for....

@acqn perhaps you can give a hint on what kind of thing could be a problem (yes i am using pragmas a lot, mostly to put things into various segments/banks)

Ok the problem is.... somehow a pragma that defines the data section gets optimized away - and now things go into a wrong section, and the result is complete screwup.

The code in question is including other C files (and headers of course), there are pragmas all over the place, and various segments are used for data and code - I'll have to try and strip it down into a test case.

That said - is the exact supposed behaviour of this stuff documented? (If not, it should be) - especially what happens at the end of a .c file when it is included by another .c file would be interesting.

Ok, that took a while, this seems to be a minimal reproducer: Not related to including .c files at all :)


#pragma code-name (push,"SEGMENT2CODE")
#pragma bss-name (push,"SEGMENT2DATA")
#pragma data-name (push,"SEGMENT2DATA")
#pragma rodata-name (push,"SEGMENT2DATA")

/* fails differently depending if initialized or not */
#if 1
static unsigned long segment2_array[42] = { 0 };
#else
static unsigned long segment2_array[42];
#endif

/* fails differently depending if static or not */
#if 1
static void segment2_func(void) {}
#else
void segment2_func(void) {}
#endif

#pragma bss-name (pop)
#pragma data-name (pop)
#pragma rodata-name (pop)
#pragma code-name (pop)


#pragma code-name (push,"SEGMENT1CODE")
#pragma bss-name (push,"SEGMENT1DATA")
#pragma data-name (push,"SEGMENT1DATA")
#pragma rodata-name (push,"SEGMENT1DATA")

static char segment1_string[] = {"foobar"};    /* BUG: this ends up in SEGMENT2DATA */

#pragma bss-name (pop)
#pragma data-name (pop)
#pragma rodata-name (pop)
#pragma code-name (pop)

No idea how to make it a proper test for the testbench....

@acqn please have a look :)

commented

Definitely a bug. Minimal example code:

#pragma data-name ("WRONG")

void f()
{
} // <- this token eats up any following #pragma's, which wil be applied before exiting the function's context

// ...which means the pragma below will actually change the name of the data-seg used in the function
// rather than the name of the data-seg used in file scope.
#pragma data-name ("CORRECT")

static char str[] = {"This should be in CORRECT"};    /* hence the BUG: this ends up in WRONG */

EDIT: So what is the solution?

  • Option 1: implement the "pragma scope" stuff introduced in 20c3e99.
  • Option 2: just revert that changeset (and unfix what it fixed).
  • Option 3: change how NextToken() works, and add code to check and apply pragma's at the beginning of every instance of code snippets where CurTok is used.

I'll choose Option 1 or 2. Option 3 requires too much work.

So what is the solution?

I can't really answer this - since i am asking you to fix this :) I am fine with whatever leaves a consistent behaviour and makes my code work again :-)

What bothers me most right now, is how to produce some test(s) for this stuff, so it doesn't break again in the future - i can't think of how that would work though shrug

commented

Well, it seems to me that the problem here can be worked around without implementing all of the "pragma scope" stuff (which eventually require an IR). Let's see if it works for you: #2367

commented

What bothers me most right now, is how to produce some test(s) for this stuff, so it doesn't break again in the future - i can't think of how that would work though shrug

Can we rely on the addresses?

Can we rely on the addresses?

Oh, i see what the idea is....

Mmmh. With a carefully crafted linker config - probably. I guess a test would have to make sure that only one "thing" goes into a section which you want to test via absolute addresses (because the order of how objects go into a section is not guaranteed)

Worth a try, i guess

Works for me now - a test would still be great, obviously :)