bebbo / amiga-gcc

The GNU C-Compiler with Binutils and other useful tools for cross development for Amiga
GNU General Public License v2.0
322 stars 66 forks source link

Creating self-relocating .library with EH is no longer possible #300

Closed Midar closed 2 years ago

Midar commented 2 years ago

Creating a self-relocating .library with EH used to be possible with amiga-gcc, however, these days, it results in the following linker warning:

.text reloc for __EH_FRAME_BEGINS__ is out of range: 00000000

That doesn't seem right. Interestingly, there is no such warning for EH_FRAME_OBJECTS? So whatever was changed only broke EH_FRAME_BEGINS. I haven't managed to track down which change broke this.

bebbo commented 2 years ago

so to say: it's more OS4/amiga-ppc compatible atm ;-)

Midar commented 2 years ago

Hah, good one! ;) But still a regression unfortunately :(

Midar commented 2 years ago

So what changed here? Is there any way to work around it?

bebbo commented 2 years ago

... to keep data segments minimal, all const stuff ends up in the .text segment. no idea without looking at the code...

does your code try to load that via a4? then it will fail.

bebbo commented 2 years ago

change

extern const void * _EH_FRAME_BEGINS__;

into

extern const void * const _EH_FRAME_BEGINS__;
Midar commented 2 years ago

Hmm, that seems to make the warning go away again, but it still fails at

        if ((size_t)_EH_FRAME_BEGINS__ != (size_t)_EH_FRAME_OBJECTS__)
                return false;

The first one used to be the count, is that no longer the case?

bebbo commented 2 years ago

comparing pointers without de-referencing? the pointers are different.

And the counters are gone, since the constructors are a relict from the past. Well, you can create counters using the linker scripts but that raises different problems,

current lib code is:

void __init_eh() {
    void ** frame = _EH_FRAME_BEGINS__;
    void ** object = _EH_FRAME_OBJECTS__;

    while (*frame) {
      __register_frame_info(*frame++, *object++);
    }
}
Midar commented 2 years ago

That seems to have worked, thanks. However, I need to change it back to non-const and get a warning, because otherwise I get an immediate crash.

Midar commented 2 years ago

Unrelated: Why are there .a files checked into the repository under lib?

bebbo commented 2 years ago

Unrelated: Why are there .a files checked into the repository under lib?

because these aren't build?

Midar commented 2 years ago

It seems that there's even more broken in amiga-gcc. It now opens the library but then just hangs. When compiling it without library support, it just says "Program aborted" - that is even if I #define abort to something that prints an error, and it never gets printed. The same code worked with older amiga-gcc and works perfectly fine when compiled for MorphOS using the MorphOS SDK. Is there any way to figure out where this abort call is coming from if not from my code?

bebbo commented 2 years ago

you need something like:

amiga-library.m

#ifdef OF_AMIGAOS_M68K
__attribute__((section(".list___CTOR_LIST__")))
const uintptr_t __CTOR_LIST__ = 0;
__attribute__((section(".list___EH_FRAME_BEGINS__")))
const uintptr_t _EH_FRAME_BEGINS__ = 0;
__attribute__((section(".list___EH_FRAME_OBJECTS__")))
uintptr_t _EH_FRAME_OBJECTS__ = 0;
#endif

and use it like

            for (const uintptr_t *frame = 1 + &_EH_FRAME_BEGINS__;
                *frame != 0;)
                libc.__deregister_frame_info((const void *)*frame++);

plus an end file: amiga-end.m

#ifdef OF_AMIGAOS_M68K
__attribute__((section(".list___CTOR_LIST__")))
long a_random_name1 = 0;
__attribute__((section(".list___EH_FRAME_BEGINS__")))
long a_random_name2 = 0;
__attribute__((section(".list___EH_FRAME_OBJECTS__")))
long a_random_name3 = 0;
#endif
bebbo commented 2 years ago

I could remove the requirement of an end file. Read here: https://github.com/bebbo/amiga-gcc/wiki/Constructors,-Destructors,-Managed-Lists