!!!!!!CORRECTION!!!!!!
When I said crtn.o in the last post, I actually meant crti.o in all of the instances I referred to it, although crtn.o also had similar issues
Perhaps I was wrong when I said I was going to be more concise this time around?
I began writing a kludge to simply force the getLocalSymbols to return all symbols in the object, and let copyLocalSymbols() deal with the work of determining which symbols were actually necessary to operate on, but then vladv informed me that llvm-objcopy would actually do most of the work of reordering the symbols correctly inside the object file. I ran it on crti.o and crtn.o, and hey, whadayya know, it worked perfectly, I didn't even have to pass any flags. This STILL wasn't the end of the global constructors saga though, I was still getting a segfault, and so I ended up spending some time researching online how the global constructors are actually called by the runtime, until I eventually found this comment on a GNU irix-crti.s file on google
Following the advice of this comment (bless you beautiful past people who left this knowledge for future porters), besides my previous -fno-use-init-array, I added -Wl,-init=__gcc_init, and -Wl,-fini=__gcc_fini to the clang command line, as well as added some extra code to 2 places in LLD to ensure that __gcc_init and __gcc_fini aren't tampered with. The next time I ran the clang/LLD output, I hit an illegal instruction error rather than a plain old segfault. I yet again did the work of stepping through the binary in GDB, and this time I found that the binary was calling the __gcc_init function and then... more or less just falling into the abyss, it ran past the end of the function and kept calling what it thought were instructions next to it in memory.
I dumped a copy of the __gcc_init symbol from clang/Binutils LD's binary, and a copy from clang/LLD's binary, and found that __gcc_init was missing some return instructions in the clang/LLD version
clang/LLD version
clang/Binutils LD version
I puzzled over this for a bit, until I decided to dump the __gcc_init symbol from all 4 C runtime object files that LLD and Binutils LD should pull in. crtbegin.o, ,crti.o, and crtend.o all appeared in both versions of the binary, the one exception was crtn.o, that object file contained the function ending/return statements, and this was what was missing from the clang/LLD version. I ran clang/LLD in verbose mode and discovered yet another IRIX quirk. Most platforms will only have 1 crtn.o, however IRIX has 2 if you're using libgcc as your runtime, one from IRIX in /usr/libXY/mipsZ/crtn.o, and another from /usr/lib/gcc/mips-sgi-irix6.5/$GCC_VERSION/crtn.o
When clang was constructing the LLD flags, it didn't know that IRIX was a bit special, so since /usr/libXY/mipsZ was higher in the path hierarchy, it pulled in the IRIX crtn.o rather than including both the IRIX crtn.o and libgcc's crtn.o. I mentioned it to vladv and he quickly wrote up a patch for this, as well as another patch to make sure the correct init and fini flags are automatically applied.
Finally, after all of this work, guess what, we got a working Hello world! from clang/LLD using libstdc++!
To be clear, the global object saga still isn't totally over, there's still bugs, and vladv's been hard at work fixing a relocation bug related to global statics in particular. But we've progressed enough now that we can get simple C++ programs to work, and I felt we'd reached a point where I could give a tangible update on progression.
Stepping away from the global objects bugs for now though, vladv is the first person in the world to run clang/LLD, targeting IRIX, on real SGI hardware under IRIX!
The reason I mostly talked about my own changes in this post is mainly because these posts are mostly about what my thought process was at the time I was making each change, and well, I'm not vladv, so I can't talk about what his thought process specifically was at the time of each change.
I'm extremely happy with all the work he's done, it's been awesome having another person who's just as motivated (possibly even more than I am) to seeing this port through, and he's incredibly sharp.
Now that vladv joined the project, the GitHub situation has sort of changed, I try and keep our 2 repositories in sync, but vladv commits way more often than I do, and he lives in a different timezone than I do, so they might fall out of sync. Thus just in case:
My Repository Link
vladv's Repository Link
If you'd like to support me financially, here's my
patreon.