ps2dev / ps2sdk

Homebrew PS2 SDK
Other
935 stars 133 forks source link

C++ static member initialization #240

Closed jendo42 closed 2 years ago

jendo42 commented 2 years ago

I don't know exactly If this is SDK related or toolchain related but I played a little bit around with the SDK and when I used C++ classes I found that the globally defined instances do not get initialized. Check the simple example below:

static std::string str = "hello";

int main(int argc, char **argv)
{
    //std::string str = "hello";
    sio_init(115200, 0, 0, 0, 0);
    sio_puts(str.c_str());
    return 0;
}

When I use the static str in debugger I can see that null is passed as this when calling c_str(). Otherwise when the string is initialized in the function context it works normally. To me it seems like there is missing some startup code to initialize the static instances. Maybe I forgot something in the build system - I do not use SDK's Makefile rather the premake5 for the project file generation and my build commands are here:

CPs2TestApp.cpp
mips64r5900el-ps2-elf-g++   -MMD -MP -DPURE_ABSTRACT= -DENTRY_POINT=int\ main\(int\ argc,\ char\ **argv\) -DENTRY_POINT_ARGS=argv -DDEBUG -DTOOLSET_GCC -D__fastcall -DFASTCALL=__attribute__\(\(fastcall\)\) -DALIGN\(x\)=__attribute__\(\(aligned\(x\)\)\) -DEXPORT=__attribute__\ \(\(visibility\ \(\"default\"\)\)\) -DARCH_MIPS -DMARVIN_PLATFORM_PS2 -D_EE -DMARVIN_USE_PS2M -DMARVIN_WITHOUT_ATOMICS -DMARVIN_USE_STDIO_ARCHIVE -DMARVIN_SINGLETHREADED -DMARVIN_API= -I../../src -Iinclude -I../../src/ps2test -I../../src/ps2test/external -I/home/jendo/Sources/ps2dev/ps2sdk/ee/include -I/home/jendo/Sources/ps2dev/ps2sdk/common/include -ffast-math -g -std=c++14 -w -fpermissive -fvisibility=hidden -fno-exceptions -G0 -march=r5900 -mtune=r5900 -nolibc  -o "obj/ps2/Debug/CPs2TestApp.o" -MF "obj/ps2/Debug/CPs2TestApp.d" -c "../../src/ps2test/CPs2TestApp.cpp"
Linking ps2test
mips64r5900el-ps2-elf-g++ -o "../build/ps2/Debug/ps2test.elf"  obj/ps2/Debug/CPs2TestApp.o   -L../../build/ps2/Debug -L/home/jendo/Sources/ps2dev/ps2sdk/ee/lib -nolibc -Wl,-zmax-page-size=128 ../build/ps2/Debug/libmarvin-core.a -lm_nano -lc_nano -lps2sdkc -lkernel-nopatch -ldebug -lmath3d

I would appreciate if somebody more expirienced will help me with this :)

rickgaiser commented 2 years ago

The global object str needs to have its "global constructor" called. These are special, becouse they are called even before main is called.

The global constructors (and destructors) are called by crt0.o, from here: https://github.com/ps2dev/newlib/blob/ee-v4.1.0/newlib/libc/sys/ps2/crt0.S#L122

Please try the latest toolchain, and also the most simple command line, like: mips64r5900el-ps2-elf-g++ CPs2TestApp.cpp -o CPs2TestApp.elf

Ziemas commented 2 years ago

You need to pass -T$(PS2SDK)/ee/startup/linkfile while linking for the startup code to be linked in.

jendo42 commented 2 years ago

Yes, the linkfile was missing. Thanks!