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

Add FreeBSD/aarch64 support #146

Merged
merged 2 commits into from Dec 15, 2018

Conversation

Projects
None yet
5 participants
@myfreeweb
Copy link

myfreeweb commented Aug 9, 2018

I hope this is correct… This makes the 0.17 bootstrap compiler work, at least.

@myfreeweb myfreeweb requested review from joakim-noah and redstar as code owners Aug 9, 2018

@joakim-noah
Copy link

joakim-noah left a comment

Have you tried running the druntime tests? ctest -R druntime-test-runner$; ./runtime/druntime-test-runner should show you what's working (check out the ldc-ltsmaster branch of druntime first and apply your patch there, so all the tests are run on a single invocation of the test runner).

Show resolved Hide resolved src/core/sys/freebsd/execinfo.d Outdated
enum _JBLEN = 31;
// __int128_t
struct _jmp_buf { long[2][_JBLEN + 1] _jb; };
}

This comment has been minimized.

@joakim-noah

joakim-noah Aug 10, 2018

Everything after the first file should go upstream at dlang/druntime, submit this there instead.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 10, 2018

druntime tests fail at CTFE stage:

/usr/home/greg/ldc/runtime/druntime/src/core/internal/hash.d(63): Error: "unable to compute hash of creal[]"
/usr/home/greg/ldc/runtime/druntime/src/core/internal/hash.d(288):        called from here: hashOf([(8.99L+86.0000Li), (3.12L+99.0000Li)
, (5.66L+12.0000Li)], 0LU)
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(114): Error: shift by 112 is outside the range 0..63                   
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(306): Error: template instance core.internal.convert.parse!(true, real)
error instantiating
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(106):        instantiated from here: denormalizedMantissa!real         
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(28):        instantiated from here: parse!(false, real)
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(315):        instantiated from here: toUbyte!real
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(326):        instantiated from here: toUbyte2!real
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(351):        instantiated from here: testNumberConvert!"-real.infinity"
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(114): Error: shift by 112 is outside the range 0..63
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(326): Error: CTFE failed because of previous errors in toUbyte2
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(326): Error: CTFE failed because of previous errors in toUbyte2
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(352): Error: template instance core.internal.convert.testNumberConvert!"
real.infinity" error instantiating
/usr/home/greg/ldc/runtime/druntime/src/core/internal/convert.d(326): Error: CTFE failed because of previous errors in toUbyte2
[…]

(& same for many more of these conversions)

After removing/commenting out these, build-druntime-test-runner passes and ./runtime/druntime-test-runner exits successfully.

(I've been working on the revision referenced from ldc lts, looks like 1 commit behind ldc-ltsmaster now)

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 10, 2018

dmd-testsuite(-debug) fails with lots of object.Exception@/usr/home/greg/ldc/runtime/phobos/std/stdio.d(2428): Enforcement failed, that is enforce(f._p && f._p.handle) (and segfault if that enforce is commented out).

All other tests in ctest pass (after disabling the ctfe described in the previous comment)

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 11, 2018

Use the patch from dlang#2257, that should fix the CTFE issue. Make sure you're on the ldc-ltsmaster branch, ie one commit ahead, or all tests won't be run without ctest.

Also, have you tried building LDC master and its druntime tests using ltsmaster? I'd like to know what happens then.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 11, 2018

(Haven't tried with patched ltsmaster yet)

ldc master segfaulted when building phobos, with an entirely unhelpful core dump (frame #0: 0x0000000000000000)

Actually, before I got to that point, there were weird initialization issues (things not being initialized) for which I made some questionable workarounds:

--- i/dmd/identifier.d
+++ w/dmd/identifier.d
@@ -182,6 +182,7 @@ nothrow:

     static Identifier idPool(const(char)* s, uint len)
     {
+        initTable();
         StringValue* sv = stringtable.update(s, len);
         Identifier id = cast(Identifier)sv.ptrvalue;
         if (!id)
@@ -240,6 +241,7 @@ nothrow:

     static void initTable()
     {
-        stringtable._init(28000);
+        if (stringtable.table == null)
+            stringtable._init(28000);
     }
 }
--- i/dmd/root/stringtable.d
+++ w/dmd/root/stringtable.d
@@ -62,7 +62,6 @@ pure:
 struct StringTable
 {
 private:
-    StringEntry* table;
     size_t tabledim;
     ubyte** pools;
     size_t npools;
@@ -70,6 +69,7 @@ private:
     size_t count;

 public:
+    StringEntry* table;
     extern (C++) void _init(size_t size = 0) nothrow
     {
         size = nextpow2(cast(size_t)(size / loadFactor));
--- i/gen/target.cpp
+++ w/gen/target.cpp
@@ -25,6 +25,7 @@
 using llvm::APFloat;

 void Target::_init() {
+  CTFloat::_init();
   FloatProperties::_init();
   DoubleProperties::_init();
   RealProperties::_init();
@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 11, 2018

Yeah, same issues on other AArch64 platforms with a natively-built LDC master, may want to try this new ltsmaster pull, ldc-developers/ldc#2811, to see what difference it makes.

Regarding the DMD testsuite issues, how do the Phobos tests do first?

ctest -R phobos2-test-runner$
./runtime/phobos2-test-runner
@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 12, 2018

Looks like I need to learn to actually read error messages! The CTFE error was @nogc function … cannot call non-@nogc … — I did not remove the @nogc when applying dlang#2257 to LTS :D

Now only dmd tests fail (that enforce in LockingTextWriter). druntime and phobos tests pass on LTS :)

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 12, 2018

See if you can bootstrap LDC master and its tests pass now with the latest version of ldc-developers/ldc#2811 applied, as I noted for other platforms. Submit all your non-__asm druntime patches upstream, versioned out for AArch64, keeping only that first file change here.

Weird that you're getting std.stdio errors in the DMD testsuite but not in the Phobos test runner, you may need to look into that in a debugger.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 12, 2018

The initialization bugs in ldc master are still there

* thread #1, name = 'ldc2', stop reason = signal SIGSEGV: invalid address (fault address: 0x6faa7af54)
  * frame #0: 0x00000000005a34c8 ldc2`_D3dmd4root11stringtable11StringTable8findSlotMxFNaNbmPxamZm + 92
    frame #1: 0x000000000051bcac ldc2`StringTable::update(char const*, unsigned long) + 68
    frame #2: 0x00000000003eb980 ldc2`Identifier::idPool(char const*, unsigned int) + 44
    frame #3: 0x00000000003d1f58 ldc2`_D3dmd10identifier10Identifier6idPoolFNbAxaZC3dmd10identifier10Identifier + 36
    frame #4: 0x00000000003edc34 ldc2`_D3dmd4cond16VersionCondition24addPredefinedGlobalIdentFAxaZv + 160
    frame #5: 0x00000000003edb60 ldc2`_D3dmd4cond16VersionCondition14addGlobalIdentFAxaZv + 60
    frame #6: 0x000000000054d664 ldc2`mars_mainBody(Array<char const*>&, Array<char const*>&) + 664
    frame #7: 0x00000000006acb34 ldc2`cppmain(argc=<unavailable>, argv=<unavailable>) at main.cpp:1060
    frame #8: 0x00000000005e6ff8 ldc2`_Dmain + 132
    frame #9: 0x00000000007eabd0 ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv + 44
    frame #10: 0x00000000007eaa58 ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 52
    frame #11: 0x00000000007eab1c ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 72
    frame #12: 0x00000000007eaa58 ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 52
    frame #13: 0x00000000007ea99c ldc2`_d_run_main + 1100
    frame #14: 0x00000000005e702c ldc2`main + 40
    frame #15: 0x00000000003c00b8 ldc2`__start(argc=232, argv=0x0000ffffffffcc88, env=0x0000ffffffffd3d0, cleanup=<unavailable>) at crt1.c:84

With the (bad) workarounds described above, I'm seeing super weird syntax errors that make zero sense, such as:

core/atomic.d(11): Error: semicolon expected, not `.`
core/atomic.d(11): Error: no identifier for declarator `.atomic`
core/atomic.d(13): Error: function declaration without return type. (Note that constructors are always named `this`)                                          
core/atomic.d(14): Error: no identifier for declarator `version(LDC)`
core/atomic.d(19): Error: found `{` when expecting `;` following statement
core/atomic.d(21): Error: found `enum` when expecting `;` following statement
core/atomic.d(23): Error: found `enum` when expecting `;` following statement
core/atomic.d(26): Error: semicolon expected, not `has128BitCAS`
core/atomic.d(26): Error: no identifier for declarator `has128BitCAS`
core/atomic.d(26): Error: declaration expected, not `=`
core/atomic.d(27): Error: unrecognized declaration
core/attribute.d(16): Error: semicolon expected, not `.`
core/attribute.d(16): Error: no identifier for declarator `.attribute`
core/attribute.d(54): Error: function declaration without return type. (Note that constructors are always named `this`)                                       
core/attribute.d(54): Error: no identifier for declarator `version(D_ObjectiveC)`                                                                             
core/attribute.d(54): Error: semicolon expected following function declaration
core/attribute.d(55): Error: semicolon expected, not `{`
core/attribute.d(55): Error: declaration expected, not `{`
core/attribute.d(57): Error: unrecognized declaration

(actually this was happening the last time as well, not segfault)

This is probably related to StringTable.

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 12, 2018

Did you apply the changes to core.stdc.stdarg too, from that pull? I had to download that patch separately.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 12, 2018

Oops I did not. Applying them results in an LLVM assertion failure:

Assertion failed: (Subtarget->isTargetDarwin() && "automatic va_arg instruction only works on Darwin"), function LowerVAARG, file /wrkdirs/usr/ports/devel/llvm60/work/llvm-6.0.1.src/lib/Target/AArch64/AArch64ISelLowering.cpp, line 4698.

Looks like that assertion is still there even in current dev llvm.

(currently building llvm without that assertion)

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 13, 2018

Huh, guess it only worked for us since we used llvm with assertions disabled.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 13, 2018

The va_list thing with assertions disabled didn't change anything. The initialization failure is not vararg related, as I expected…

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 13, 2018

I'm skeptical that you're having some other non-va_list problem, as that pull got ldc master working for me on linux and Android/AArch64. I suppose it's possible that FreeBSD/AArch64 isn't using the AAPCS ABI or uses some APCS variant like iOS does, up to you to figure it out.

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 13, 2018

The initialization failure is not vararg related, as I expected…

Yep, it almost certainly isn't. By the looks of it, the module ctors aren't run; this might also cause your std.stdio:2428 issue. E.g., CTFloat::_init() is supposed to be called by the dmd.root.ctfloat module ctor by (the host compiler's) druntime (before main()), way before calling Target::_init() manually in dmd.mars.

[Changing a struct layout on one side only (D/C++), e.g., moving member StringEntry* table from first to last field, without adapting the C++ header too, makes things explode if the C++ code works with that struct and member too.]

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 13, 2018

Yeah, that's it:

import core.stdc.stdio;
shared static this() { printf("shared static\n"); }
shared static ~this() { printf("~shared static\n"); }
static this() { printf("static\n"); }
static ~this() { printf("~static\n"); }
void main() { printf("main\n"); }

(compiled with LTS) only prints "main".

Stepping through rt_moduleCtor in lldb finishes very quickly… (unfortunately LTSmaster doesn't seem to produce proper debug info)

@joakim-noah joakim-noah referenced this pull request Aug 13, 2018

Open

[tracker] AArch64 progress #2153

12 of 17 tasks complete
@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 13, 2018

So, there's no SectionGroups, but only when linking with LLD. Linking the above test with cc -fuse-ld=gold, the constructors/destructors run!

And there's Fatal error in EH code: _Unwind_RaiseException failed with reason code: 5 after ~shared static is printed:

* thread #1, name = 'ctortest', stop reason = signal SIGABRT
  * frame #0: 0x000000004066f464 libc.so.7`__sys_thr_kill + 8
    frame #1: 0x000000004066f430 libc.so.7`raise + 64
    frame #2: 0x000000004066f3a4 libc.so.7`abort + 84
    frame #3: 0x000000000041735c ctortest`fatalerror + 156
    frame #4: 0x000000000040d358 ctortest`onOutOfMemoryError + 32
    frame #5: 0x000000000040c784 ctortest`_D2rt4util9container6common8xreallocFNbPvmZPv + 76
    frame #6: 0x000000000040aa5c ctortest`_d_dso_registry + 164
    frame #7: 0x000000000042ff80 ctortest`ldc.dso_dtor.2rt7switch_ + 96
    frame #8: 0x000000004046b308 ld-elf.so.1
    frame #9: 0x0000000040465b50 ld-elf.so.1
    frame #10: 0x00000000406d7220 libc.so.7`__cxa_finalize + 172
    frame #11: 0x000000004066efe8 libc.so.7`exit + 44
    frame #12: 0x0000000000402414 ctortest`__start(argc=<unavailable>, argv=<unavailable>, env=<unavailable>, cleanup=<unavailable>) at crt1.c:84

Linking with cc -fuse-ld=bfd, everything prints and no error!

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 13, 2018

Nice findings. Seems to be related to problems with llvm.global_{c,d}tors (which we use to call the auto-generated ldc.register_dso function at startup/termination, per D module). These {c,d}tors are supposed to be called by the C runtime AFAIK (such as __cxa_finalize in your call stack after C main() returns). May be FreeBSD specific though (at least the issue with gold); Shippable CI is using gold (but bfd works too, but issues lots of TLS-related warnings with clang as C++ host compiler).

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 13, 2018

Yeah, I'm seeing TLS related warnings with bfd too.

Temporarily changed /usr/bin/ld to ld.bfd instead of the default ld.lld, discovered a new error, now in GC:

* thread #1, name = 'ldc2', stop reason = signal SIGSEGV: invalid address (fault address: 0x0)                                                                                             
  * frame #0: 0x0000000000d062c8 ldc2`_D2gc2gc3Gcx4markMFNbPvPvZv + 132                                                                                                                    
    frame #1: 0x0000000000cb87c4 ldc2`_D4core6thread14thread_scanAllUNbMDFNbPvPvZvZ43__T9__lambda2TE4core6thread8ScanTypeTPvTPvZ9__lambda2MFNbE4core6thread8ScanTypePvPvZv + 60            
    frame #2: 0x0000000000cb8748 ldc2`_D4core6thread15scanAllTypeImplFNbMDFNbE4core6thread8ScanTypePvPvZvPvZ20__T9__lambda3TPvTPvZ9__lambda3MFNbPvPvZv + 60                                
    frame #3: 0x0000000000ce4da8 ldc2`_D2rt19sections_elf_shared13scanTLSRangesFNbPS2rt4util9container5array13__T5ArrayTAvZ5ArrayMDFNbPvPvZvZv + 204                                       
    frame #4: 0x0000000000ce881c ldc2`_D2rt5tlsgc4scanFNbPvMDFNbPvPvZvZv + 40                                                                                                              
    frame #5: 0x0000000000cb86d0 ldc2`_D4core6thread15scanAllTypeImplFNbMDFNbE4core6thread8ScanTypePvPvZvPvZv + 380                                                                        
    frame #6: 0x0000000000cb8548 ldc2`_D4core6thread18thread_scanAllTypeUNbMDFNbE4core6thread8ScanTypePvPvZvZ17__T9__lambda2TPvZ9__lambda2MFNbPvZv + 48                                    
    frame #7: 0x0000000000cb55a4 ldc2`_D4core6thread18callWithStackShellFNbMDFNbPvZvZv + 112                                                                                               
    frame #8: 0x0000000000cb84f4 ldc2`thread_scanAllType + 56                                                                                                                              
    frame #9: 0x0000000000cb877c ldc2`thread_scanAll + 40                                                                                                                                  
    frame #10: 0x0000000000d071c8 ldc2`_D2gc2gc3Gcx7markAllMFNbbZv + 128                                                                                                                   
    frame #11: 0x0000000000d02944 ldc2`_D2gc2gc3Gcx11fullcollectMFNbbZm + 584                                                                                                              
    frame #12: 0x0000000000d04808 ldc2`_D2gc2gc3Gcx10smallAllocMFNbhKmkZPv + 516                                                                                                           
    frame #13: 0x0000000000cfff88 ldc2`_D2gc2gc3Gcx5allocMFNbmKmkZPv + 236                                                                                                                 
    frame #14: 0x0000000000cffe3c ldc2`_D2gc2gc2GC12mallocNoSyncMFNbmkKmxC8TypeInfoZPv + 184                                                                                               
    frame #15: 0x0000000000d0008c ldc2`_D2gc2gc2GC6callocMFNbmkPmxC8TypeInfoZPv + 224                                                                                                      
    frame #16: 0x0000000000ccfa3c ldc2`gc_calloc + 80                                                                                                                                      
    frame #17: 0x0000000000cb2eec ldc2`_D4core6memory2GC6callocFNaNbmkxC8TypeInfoZPv + 36                                                                                                  
    frame #18: 0x0000000000cd36a0 ldc2`_D2rt3aaA12allocBucketsFNaNbNemZAS2rt3aaA6Bucket + 48                                                                                               
    frame #19: 0x0000000000cd354c ldc2`_D2rt3aaA4Impl6__ctorMFNcxC25TypeInfo_AssociativeArraymZS2rt3aaA4Impl + 112                                                                         
    frame #20: 0x0000000000cd5794 ldc2`_d_assocarrayliteralTX + 252                                                                                                                        
      frame #21: 0x00000000008409e8 ldc2`_D3dmd7imphint19_sharedStaticCtor10FZv + 80
    frame #22: 0x0000000000ce1aa8 ldc2`_D2rt5minfo67__T14runModuleFuncsS442rt5minfo11ModuleGroup8runCtorsMFZ9__lambda2Z14runModuleFuncsMFAxPyS6object10ModuleInfoZv + 196                 
    frame #23: 0x0000000000ce18e4 ldc2`_D2rt5minfo11ModuleGroup8runCtorsMFZv + 128
    frame #24: 0x0000000000ce22a4 ldc2`_D2rt5minfo13rt_moduleCtorUZ14__foreachbody1MFKS2rt19sections_elf_shared3DSOZi + 48                                                                
    frame #25: 0x0000000000ce3ce0 ldc2`_D2rt19sections_elf_shared3DSO7opApplyFMDFKS2rt19sections_elf_shared3DSOZiZi + 184                                                                 
    frame #26: 0x0000000000ce2264 ldc2`rt_moduleCtor + 24
    frame #27: 0x0000000000cd8dd0 ldc2`rt_init + 192
    frame #28: 0x0000000000cd9928 ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZv + 36
    frame #29: 0x0000000000cd9888 ldc2`_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ7tryExecMFMDFZvZv + 48
    frame #30: 0x0000000000cd97e8 ldc2`_d_run_main + 1696
    frame #31: 0x0000000000932db4 ldc2`main + 40
    frame #32: 0x000000000069d378 ldc2`__start(argc=232, argv=0x0000ffffffffcc90, env=0x0000ffffffffd3d8, cleanup=<unavailable>) at crt1.c:84

hmm — TLS is mentioned in the backtrace.

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 14, 2018

The GC is running in your LDC? That doesn't make sense, LDC doesn't use the D GC internally.

@dnadlinger

This comment has been minimized.

Copy link
Member

dnadlinger commented Aug 14, 2018

Seems like the GC isn't disabled early enough…

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 15, 2018

So just to be sure, all the same tests pass for ltsmaster once you started using ld.bfd? Also, you never saw test failures there with std.stream and std.numeric, among others listed in ldc-developers/ldc#2153? Those modules have not been fully ported to AArch64 yet, as noted there.

You can remove the changes from this pull that were merged upstream, I will just cherry-pick that commit.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 15, 2018

Yeah, all the same tests pass on ltsmaster — only dmd fails. Never saw other failures.

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 15, 2018

The GC segfault above indicates invalid TLS ranges, which might depend on the linker again.

Seems like the GC isn't disabled early enough…

Yep indeed, but that looks like an upstream issue. https://github.com/ldc-developers/ldc/blob/master/dmd/imphint.d#L34-L43 leads to a _d_assocarrayliteralTX() call (for DMD too) in a module ctor, before the GC is disabled in D main() (for DMD too). There's no corresponding _d_assocarrayliteralTX override in dmd.root.rmem (again, neither for DMD).

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 15, 2018

Since bfd has emitted TLS warnings, it certainly might have screwed this up. I need to get LLD working (fix the section groups thing), but I don't really know what to look for. Can I do something with objdump/readelf to compare the binaries made by different linkers?

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 15, 2018

Not so sure about the TLS warnings; I quickly looked them up, and they are apparently safe to discard (and should be fixed with clang 7).

Can I do something with objdump/readelf to compare the binaries made by different linkers?

Sure. Use something minimal (with -betterC, add a extern(C) void main() {} for the executable) such as https://run.dlang.io/is/3DughW and make sure it doesn't work with LLD, but with bfd. Then check the IR, which should add the init function to the global static ctors:

@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @void onlineapp.init(), i8* null }] ; [#uses = 0]

Then check the asm of the object file, where you should find an init pointer in the special .init_array section:

.section	.init_array,"aw",@init_array
.p2align	3
.xword	void onlineapp.init() ; run.dlang.io automatically demangles...

Then finally compare the bfd/lld-linked binaries, sections, symbols etc. There might be missing (linker-magic) symbols bracketing a section and whatnot.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 16, 2018

Looks like ltsmaster doesn't support betterC nor crt_constructor… Looking at IR from a non-betterC example, global_ctors references a generated function that does the ModuleInfo stuff. I'm pretty sure that gets called just fine — the problem was it not finding the ModuleInfos.

The various symbols with "moduleinfo" in the name don't seem to look different…

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 16, 2018

I was just looking into this: no __minfo back in ltsmaster, but lld probably missing some magic symbols like you said.

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 16, 2018

I rather think it's wrongly stripping them out (llvm.used unused in ltsmaster?); we'd have linker errors if the magic symbols were missing.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 16, 2018

comparing section sizes (.init_array and __minfo)

heh — that's what I just started doing… but wasn't aware of init_array — which turned out to have different size!

~/ldc % objdump -h testconstr-bfd | grep minfo
 27 .minfo_beg    000001d8  00000000004581e8  00000000004581e8  000481e8  2**3
 28 .minfo        000001d8  00000000004583c0  00000000004583c0  000483c0  2**3
 29 .minfo_end    000001d8  0000000000458598  0000000000458598  00048598  2**3
~/ldc % objdump -h testconstr-lld | grep minfo
 19 .minfo_beg    000001d8  0000000000064ca0  0000000000064ca0  00054ca0  2**3
 20 .minfo        000001d8  0000000000064e78  0000000000064e78  00054e78  2**3
 21 .minfo_end    000001d8  0000000000065050  0000000000065050  00055050  2**3
~/ldc % objdump -h testconstr-lld | grep init_array
 28 .init_array   00000008  00000000000703e0  00000000000703e0  000603e0  2**3
~/ldc % objdump -h testconstr-bfd | grep init_array
 18 .init_array   000001e0  0000000000452c58  0000000000452c58  00042c58  2**3
@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 16, 2018

binaries: lld bfd

for this source:

import core.stdc.stdio;

shared static this() { printf("this\n"); }

void main() {}
@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 16, 2018

As already mentioned, that .init_array section contains the pointers of the llvm.global_ctors functions, so 1 vs. 60 functions... Maybe try googling for known issues with .{init,fini}_array for lld/gold on AArch64 (and FreeBSD?). Are you using recent versions?

@joakim-noah

This comment has been minimized.

Copy link

joakim-noah commented Aug 16, 2018

What I mean is that ltsmaster predates generating a __minfo section altogether, used _Dmodule_ref linked list back then, maybe that symbol's getting stripped out?

Update: Never mind, I now see it was using explicitly generated .minfo_{beg,end} symbols on FreeBSD back then, not magic ones.

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 16, 2018

sections_ldc.d

I don't think that's used, sections_elf_shared.d is there and supports FreeBSD

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 16, 2018

What I mean is that ltsmaster predates generating a __minfo section altogether

[That file isn't used for Linux and FreeBSD (it really just seems to be used as fallback for unknown OS), sections_elf_shared.d is used. Seems like the section name is slightly different in ltsmaster (plus no magic linker symbols, manual .minfo_{beg,end} bracketing symbols instead?).]

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Aug 16, 2018

googling for known issues with .{init,fini}_array for lld/gold on AArch64

I can only find relocation-related issues for that…

Are you using recent versions?

The default linker is lld 6. I also tried 5.0 and lld-devel (7.0.d20180523), same results. bfd is from binutils-2.30.

contains the pointers of the llvm.global_ctors functions, so 1 vs. 60 functions

I'm not sure where 60 would come from?

@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ldc.dso_ctor.10testconstr, i8* null }] ; [#uses = 0]
@kinke

This comment has been minimized.

Copy link
Member

kinke commented Aug 16, 2018

I'm not sure where 60 would come from?

druntime (+ C libs possibly). There's one ctor/dtor per (linked-in) D object file. 60 ctors also more or less match the 59 (0x1d8 / 8) ModuleInfos. Note that LDC master uses --gc-sections for linking by default on Linux, so you may want to try -disable-linker-strip-dead in case you haven't tried disabling stripping yet. Ah, you're on FreeBSD. ;)

@myfreeweb myfreeweb force-pushed the myfreeweb:freebsd-aarch64 branch from d52a955 to 791a801 Oct 16, 2018

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Oct 25, 2018

Huh, new FreeBSD commit: https://reviews.freebsd.org/D17587

"Implement a BSD licensed crtbegin/crtend" "These are needed for .ctors/.dtors and .jcr handling" "Perhaps put a comment here that arm64 does not use .ctors/.dtors or such?"

I'll ask about this…

UPD: facepalm, we were already talking about init_array here, not ctors

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Oct 25, 2018

So looks like the object file from the compiler has the ctors as .ctors, bfd and gold linkers do convert that to init_array (apparently as an optimization!!!), but lld does not.

And why are there .ctors? Because ldc (at least ltsmaster) doesn't have anything like this piece of clang code:

https://github.com/llvm-mirror/clang/blob/5897428cd24e2deefbcc6f6744c0d7d233aa6747/lib/Driver/ToolChains/Gnu.cpp#L2598-L2620

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Nov 4, 2018

So the GC issue is still present (when linking with lld).

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Nov 4, 2018

Just with LLD?

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Nov 4, 2018

bfd too (you can see above, I first discovered it with bfd, thought it might be bfd's fault, but no)

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Nov 4, 2018

I suspect a FreeBSD-specific problem in section_elf_shared.d's getTLSRange() and/or scanSegments() in there, i.e., when trying to establish the TLS address range for the executable, based on the ELF header and __tls_get_addr().

I'd suggest using -link-debuglib (I think that's the old name for ltsmaster) to link against debug druntime (and -g obviously) and then debugging with appropriate breakpoints - a dummy executable should do, just perform a dummy allocation and then GC.collect(). If ltsmaster's debuginfos aren't sufficient, you can always add some printfs. You can also add a thread-local global in your dummy source file and print its address, so that you can verify druntime's TLS range.

@strejda

This comment has been minimized.

Copy link

strejda commented Dec 13, 2018

I hope that this problem was fixed by https://svnweb.freebsd.org/changeset/base/341512 But 'rust' itself needs additional patch, which is currently in review state. I hope that I will be able to commit it in next few days. (Bulk ports compile is still in progress to verify this patch, RTLD TLS handling is complicated from time to time).

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Dec 13, 2018

Yes, looks like this was the same problem that was screwing up Rust. I'm not sure if D18417 is necessary for LDC or r341512 is enough, but I'm on a kernel with D18417 applied currently.

Thanks @strejda!


Now I have built ldc2, tests are mostly running out of memory (because I built ldc2 in debug mode :D), building dub failed with Assertion failed: ((!Node || !ResNo || ResNo < Node->getNumValues()) && "Invalid result number for the given node!"), function SDValue, file /wrkdirs/usr/ports/devel/llvm70/work/llvm-7.0.0.src/include/llvm/CodeGen/SelectionDAGNodes.h, line 1101 (BTW turns out that FreeBSD shipping LLVM with assertions was not intentional, it was a CMake accident), but simple examples like the one from the bottom of this page work fine! :)

Sooooo the changes I have in my repos are:

  • ltsmaster:
  • ldc2:
    • enabling PIC by default (I'll send that as a PR) ldc-developers/ldc#2938
    • druntime:
      • what's currently in this PR (the asm thing)
      • 64-bit inode changes for FreeBSD 12

UPD: backtrace isn't actually working, I'm probably writing into the variable and not to where the variable points to, trying that fix. But why aren't we using libbacktrace?…

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Dec 13, 2018

The -O -g dub issue is ldc-developers/ldc#1989.

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Dec 13, 2018

I'm probably writing into the variable and not to where the variable points to

Yep edit: The other way around, you're currently writing into the void** value (which should be initialized with null). Use &p to set p instead.

@myfreeweb myfreeweb force-pushed the myfreeweb:freebsd-aarch64 branch from 791a801 to 0802f36 Dec 14, 2018

@myfreeweb

This comment has been minimized.

Copy link
Author

myfreeweb commented Dec 14, 2018

Backtrace works now, thanks!

Updated this PR.

@kinke kinke merged commit 98321e0 into ldc-developers:ldc Dec 15, 2018

@kinke

This comment has been minimized.

Copy link
Member

kinke commented Dec 15, 2018

I've also cherry-picked it to ltsmaster. - The other patches you cherry-picked for ltsmaster aren't required to build it and then use it for building master, right? They aren't for Linux/AArch64 and don't seem FreeBSD specific (dlang@ce863ec shouldn't be an issue, as LDC itself is usually linked against static druntime).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.