It turns out that there was no GHDL empty-string bug - null-length strings are not legal in VHDL! I can't comment on why the VHDL creators implemented something this bizarre, (it may be a holdover from ADA, which VHDL came from) but I have decided to work around it for now by terminating all strings with an ASCII 25(decimal) character, which specifies "end of medium" and isn't commonly used anymore. Wierd, but it seems to be working - I have converted the strlib_* routines as well as libc_gets() to use the new marker and it looks like it is OK now.
Now I need to start fixing some bugs in the 'ls' command and with the libc_scandir() bridge code it calls. The base libc scandir() function allocates memory for a variable-length dirent list internally, due to the fact that the caller doesn't know in advance how many entries a directory will contain. I'm not yet ready to do much dynamic allocation in Controlix yet, so it will probably be necessary to allocate a large fixed-length list in both the C-language shim and the VHDL code in libc_scandir.vhdl so I can hold (within reason) whatever results scandir() returns.
Onward....