fix duplicate _Dmain() declaration - #23484
Conversation
|
0ce685b to
65a484a
Compare
|
@thewilsonator thank you! |
|
where is the file compilable/vcg-ast.d.cg ? |
|
it is the output of the test |
So what was/is the real problem? The user defines |
|
I don't understand how this could possibly cause a failure. Is the linker crashing? Is there an error message? |
|
The problem is it produces two entries for _Dmain in the symbol table. One is N_SECT, the other is N_UNDF. Both appear in relocations. The error: Sending the object file through chatgpt says the duplicate symbols in the symbol table is invalid. |
|
What I'm having difficulty with is what is the path to the test case? I found it for the others, but not Ubuntu. |
|
Chatgpt sez: I already removed the duplicate _main in a previous PR. |
|
Well this seems to be a DMD-backend-specific issue then (for macOS arm64), no need to change druntime because of this. |
|
Apparently not just macOS arm64 specific AFAICT.
Using DMD v2.112.0 on Linux:: $ dmd -c maintest.d
$ nm maintest.o
0000000000000000 t
0000000000000000 R _D8maintest12__ModuleInfoZ
U _d_dso_registry
0000000000000000 W _Dmain
U _Dmain
U _d_run_main
U _GLOBAL_OFFSET_TABLE_
U _main
0000000000000000 W main
U __start_minfo
U __stop_minfoLDC v1.42.0 in comparison: $ ldc2 -c maintest.d
$ nm maintest.o
0000000000000000 V _D8maintest11__moduleRefZ
0000000000000000 D _D8maintest12__ModuleInfoZ
0000000000000000 T _Dmain
U _d_run_main
0000000000000000 T mainSo I guess it's just the Apple linker which complains about DMD not folding the 2 declarations to the single definition in that one object file. |
|
I've had a number of issues with the Apple Arm64 linker in that it adds undocumented requirements to the object file format. None of the other linkers have a problem with this. The fix is in the dmd front end, so it shouldn't affect your work at all. If I was to change the dmd backend to fold it, it would require building a symbol table, which will significantly slow down the compiler. |
Yeah I was afraid of something like that. If it's really such a slow-down, maybe you can only use it for macOS arm64, as the Apple linker seems pickier than for x86_64 and require these unique symbols? Note that users would also hit this with similar code, compiling a module with the definition and another module with a fwd-declaration to the same object file. Can also happen for weird code like this: void foo() {}
pragma(mangle, foo.mangleof)
void bar();
// reference bar
void baz() { bar(); } |
|
You're right about the pragma mangle thing, but I regard that as "user should know what he is doing" when doing things like that, similar to using inline assembler. DMD can compile entire programs as one object file (I build DMD that way!), and that means a very very large number of symbols and corresponding relocations that would have to be merged. The existing |
|
This mangle trick is also how |
|
You also get multiple symbol table entries without pragma(mangle): module mod;
extern(C) int foo();
int main()
{
return foo();
}module mod1;
extern(C) int foo()
{
return 2;
}Compiled to a single object file: Also happens on Windows: This pretty much matches the _Dmain case. |
The reference file is compilable/extra-files/vcg-ast.d.cg |
|
oh hell |
I found the source of the duplicate declaration of _Dmain(), which causes the Mac Arm64 linker to fail. One is the one declared in the user's program, the other was in core.internal.entrypoint, where it was declared in the scope of _d_cmain(). The names were mangled the same (both as _Dmain).
The easiest way to fix that was to pass the correct _Dmain declaration in as an alias argument to the _d_cmain template.