Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems handling weak and external symbols #289

Closed
hitman-codehq opened this issue Jun 29, 2022 · 17 comments
Closed

Problems handling weak and external symbols #289

hitman-codehq opened this issue Jun 29, 2022 · 17 comments
Labels
close pending waiting for feedback to close this issue

Comments

@hitman-codehq
Copy link

I have a system for automatically opening libraries that depends on external symbols. One uses it like this:

File.c:

extern struct Library *IntuitionBase;

printf("IntuitionBase = %p\n", IntuitionBase);

Then at link time, you link with a library that defines IntuitionBase as a weak symbol. Some linker magic then happens which includes this symbol and its module in the executable, thus causing the library to be opened. For libraries that don't have anything referencing their base, their modules don't get included and so the library does not get opened.

It's probably easiest to show with an example. I simplified the bug to two files in the attached WeakSymbols.zip file. TestIntuition.c, which declares and uses IntuitionBase like above, and AutoIntuition.c, which contains the declaration of the IntuitionBase symbol.

Just compile it like this:

m68k-amigaos-gcc AutoIntuition.c TestIntuition.c -o TestIntuition

If you compile it with last year's 210321150254 GCC release and run the executable on AmigaOS, you output something like this:

$ TestIntuition
IntuitionBase = 0x700b62c

But if you compile it with the latest snapshot, you get this:

$ TestIntuition
IntuitionBase = 0x00000000

So it seems that the IntuitionBase symbol is being imported from AutoIntuition.c (because there is no linker error about an undefined symbol) but the OpenIntuitionBase() function, which has the constructor attribute assigned to it, is not getting called, so intuition.library does not get opened.

One interesting (but possibly irrelevant) thing is that the old 210321150254 release gives a warning when compiling the AutoIntuition.c file:

$ m68k-amigaos-gcc AutoIntuition.c TestIntuition.c -o TestIntuition
AutoIntuition.c:6:39: warning: weak declaration of 'IntuitionBase' not supported
 __attribute__((weak)) struct Library *IntuitionBase;

But then it works anyway (it also works if the weak attribute is removed). The warning does not appear when compiling with the latest snapshot.

I tried compiling Amiga GCC using an older snapshot of the amiga-gcc tree but the problem is still happening. So it seems that it is being caused by a newer version of some subproject that is getting pulled in in the projects subdirectory, rather than a change made to code in the amiga-gcc tree itself.

WeakSymbols.zip

@bebbo
Copy link
Owner

bebbo commented Jun 30, 2022

the reason is: the constructor attribute no longer works. Constructors still do work, since gcc emits code not using this attribute

You have to use

#include "stabs.h"

...

ADD2INIT(OpenIntuitionBase, -10);
ADD2EXIT(CloseIntuitionBase, -10);

the lower the number the early it gets invoked. Stdio is initialized with -30. The constructors are called at -5.

And you could simply use the libnix library which already provides what you are doing:

m68k-amigaos-gcc -noixemul -Os TestIntuition.c -o TestIntuition

@hitman-codehq
Copy link
Author

Thanks for getting back to me. I was just wondering what the reason was that this feature was removed? It was quite useful. I can add the stabs.h code myself, but other people might also have a problem.

I tried your solution of using libnix and it works, although LayoutBase is missing so I had to manually add it to my code. I could probably submit a PR to add that to libnix.

Normally I am using clib2. Is there any documentation about the -noixemul flag? I am wondering about the following:

m68k-amigaos-gcc -noixemul => Using libnix
m68k-amigaos-gcc => Using ixemul?
m68k-amigaos-gcc -mcrt=clib2 => Using clib and ixemul?

Is this correct? Perhaps I have accidentally been linking with both ixemul and clib2 in my code.

Sorry for all of the questions and thanks for the help!

@bebbo
Copy link
Owner

bebbo commented Jul 9, 2022

Please have a look into the wiki here.

@bebbo bebbo added close pending waiting for feedback to close this issue labels Jul 11, 2022
@hitman-codehq
Copy link
Author

Thanks for the information!

@hitman-codehq
Copy link
Author

I'm a bit confused. I've updated my code and it is working for simple examples but not for something more complex. I suspect something is getting executed before my startup code. You said:

the lower the number the early it gets invoked. Stdio is initialized with -30. The constructors are called at -5.

When you say the constructors are called at -5, do you mean the ADD2INIT and ADD2EXIT macros?

@hitman-codehq
Copy link
Author

I also have another problem. I switched to using -noixemul but my Reaction based .image and .gadget libraries do not load. For each one, I get the following error:

bitmap.library failed to load

It seems that the library is trying to open them as "normal" libraries. In this case, the library should be loaded as bitmap.image (from the Sys:Classes/Images directory).

The strange thing is that I tried your suggestion a couple of weeks ago and it worked. Has something changed since then?

@hitman-codehq hitman-codehq reopened this Jul 20, 2022
@bebbo
Copy link
Owner

bebbo commented Jul 21, 2022

Thanks for getting back to me. I was just wondering what the reason was that this feature was removed? It was quite useful. I can add the stabs.h code myself, but other people might also have a problem.

It simply did not work in all cases. Feel free to fix the Amiga linker code to get it working the old way.

@bebbo
Copy link
Owner

bebbo commented Jul 21, 2022

I also have another problem. I switched to using -noixemul but my Reaction based .image and .gadget libraries do not load. For each one, I get the following error:

bitmap.library failed to load

It seems that the library is trying to open them as "normal" libraries. In this case, the library should be loaded as bitmap.image (from the Sys:Classes/Images directory).

It seems that you are using new stuff with a name conflict to old stuff:

==id $Id: bitmap_lib.sfd 1.1 1999/10/06 10:13:25 olsen Exp olsen $
==base _BitMapBase
==basetype struct Library *
==libname bitmap.library
==bias 30
==public
==include <intuition/intuition.h>
==include <intuition/classes.h>
Class * BITMAP_GetClass() ()
==end 

means that there existed (was planned?) a bitmap.library.

You can initialize your library yourself by providing an instantiated variable. A declaration or a definition is not enough:

WhatEverType * BitMapBase = NULL;

No auto-open will occur for this BitMapBase variable.

The strange thing is that I tried your suggestion a couple of weeks ago and it worked. Has something changed since then?

How would I know what you tried and how long a couple of weeks is? /shrug

@hitman-codehq
Copy link
Author

It simply did not work in all cases. Feel free to fix the Amiga linker code to get it working the old way.

I think that would take me about a year to figure out. :-) I am sure that it is quite difficult for you to make this and I appreciate it!

I found another problem related to this - not only are the functions marked as attribute((constructor)) not being called, but global C++ constructors are not called either. It took some debugging to track this down because my Amiga just hangs. It's easy to reproduce and I've attached a test case. Just compile it with "m68k-amigaos-g++ Constructor.cpp". If you use an older release of amiga-gcc then it works and prints out "In MyClass constructor" when you run the executable. Compile it with a new release and it doesn't print anything.

Thanks and let me know if you need any more information!

Constructor.zip

@bebbo
Copy link
Owner

bebbo commented Jul 23, 2022

It works as expected:

> m68k-amigaos-g++ -noixemul -Os Constructor.cpp -o Constructor
> vamos Constructor
In MyClass constructor

@bebbo
Copy link
Owner

bebbo commented Jul 23, 2022

also works in WinUAE:
image

@hitman-codehq
Copy link
Author

Hello Bebbo.

I did a git pull and fresh recompile to make sure I've got the latest source and have some more results: It is the clib2 build the constructor does not work with:

m68k-amigaos-g++ -mcrt=clib2 Constructor.cpp -o Constructor.clib2

Of course, clib2 is the build I have been using!

I also found another curiosity. This also does not work:

m68k-amigaos-g++ Constructor.cpp

But what library is this using by default? All other libraries work but not clib2 and not the default. But the default one creates a binary of a different size to all of the others, so I am wondering what library it is using.

-rwxrwx--- 1 root vboxsf 18184 Jul 28 07:21 Constructor -rwxrwx--- 1 root vboxsf 24384 Jul 28 07:21 Constructor.clib2

Thanks as always for the help.

@mheyer32
Copy link
Contributor

Try passing -v to the compiler to see the detailed invocation parameters

@hitman-codehq
Copy link
Author

Try passing -v to the compiler to see the detailed invocation parameters

I had a look and there are a bunch of clib2 related defines and a library path added, but I didn't see anything to explain what is getting built when no -m parameter is passed. I would expect the size to be identical to one of the other builds when no -m parameter is passed (i.e. The build defaults to clib2, nix20 etc. 🧐

@bebbo
Copy link
Owner

bebbo commented Nov 25, 2022

I adapted the clib2 here to use the section based INIT stuff. Constructors do work again.

@hitman-codehq
Copy link
Author

Hello again @bebbo. I took some time to rebuild the latest Amiga GCC on MacOS and Linux can can confirm that it is able to successfully build my software again, and the software works! Many thanks for your work in making this happen - I know some of these GCC issues you have to solve are pretty tough, so it's really appreciated! 😎😁🤩

@bebbo
Copy link
Owner

bebbo commented Dec 1, 2022

you are welcome

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
close pending waiting for feedback to close this issue
Projects
None yet
Development

No branches or pull requests

3 participants