Generate memory and table imports/exports in web assembly - clang

The default code generation for compiling with LLVM/Clang to WebAssembly exports memory and ignores tables completely.
Is there a way to emit memory and table imports (and/or exports) when targeting web assembly with clang (--target=wasm32-unknown-unknown-wasm)?

LLD with -flavor wasm has been rolled back into upstream LLVM which does give the ability to decide wether memory and function tables should be imported or exported.

Related

How to prevent 'The code execution cannot proceed because xxx.dll was not found' error if DLL is not present

We have developed a DLL in Delphi 10 that we use in some legacy Delphi 6 applications. The new functionality in the DLL is only for a few clients and is therefore not required to roll out to all our clients. If we try to deploy the Delphi 6 application without the DLL we get the error "The code execution cannot proceed because xxx.dll was not found.". We get the error the moment the app starts to run. Is there a way to prevent this error if the DLL does not exist? In our Delphi 6 code we already use FileExists(xxx.dll) to see if we should make the functionality in the DLL available therefore we don't have the risk that the application will crash if the dll is not present.
We would also be keen to learn where/when the Delphi 6 app checks if the DLL exists because it happens before the Application.Initialize, which is the first line of code in the DPR file.
This type of failure is caused by statically (aka : implicitly) linking the DLL. There is no option if you have chosen to use static linking - the DLL must be present on the system trying to run the application.
There are two ways to allow the DLL to be optionally present.
One is to rewrite the affected sections of code to use dynamic linking (aka : explicit ) for your DLLs instead of static linking. For Delphi 6, this is unfortunately your only option.
The other, an option if you are targeting Windows only and if you are compiling with Delphi 2010 or greater, is to use delayed loading by decorating your import declarations with the delayed directive:
function GetSomething: Integer; external 'somelibrary.dll' delayed;
This is really just syntactic sugar resting on top of what is otherwise dynamic loading, but it does provide an easier path to migrate statically linked code to a dynamic linked model without needing an extensive rewrite.
From Embarcadero :
The delayed directive is useful in the case where the imported routines do not exist on the target operating system on which the application is run. Statically imported routines require that the operating system find and load the library when the application is started. If the routine is not found in the loaded library, or the library does not exist, the Operating System halts the execution of the application. Using the delayed directive enables you to check, at run time, whether the Operating System supports the required APIs; only then you can call the imported routines.
Note: Trying to call a delayed routine that cannot be resolved results in a run-time error (or an exception, if the SysUtils unit is loaded).
In either case, delayed or dynamic loading, you would need to catch the failure to resolve the DLL and gracefully deny users access to whatever functions the DLL provides.

Enable Safe Exception Handling in C++ Builder

For Windows 8 application certification, there are (among other) these requirements:
3.2 Your app must be compiled using the /SafeSEH flag to ensure safe exceptions handling
3.3 Your app must be compiled using the /NXCOMPAT flag to prevent data execution
3.4 Your app must be compiled using the /DYNAMICBASE flag for address space layout randomization (ASLR)
I wasn't able to find out how to enable either of these in C++Builder XE.
For /NXCOMPAT and /DYNAMICBASE, one can use editbin.exe from VS or peflags.exe from Cygwin. Though I would feel more confident about possible side-effects, if there was native way to enable these.
Anyway, I'm totally at loss regarding /SafeSEH.
First, /SafeSEH only applies to x86, not x64 or ARM. It requires that your compiler generate additional tables indicating the function addresses that are considered valid exception handlers for security reasons. There's a slim chance you could do this yourself, but it would require that you look at the fs:0 exception handling chain in your compiled assembly code and enumerate all addresses that are ever pushed on that chain, then describe them as documented here: http://msdn.microsoft.com/en-us/library/9a89h429(v=VS.80).aspx. There's a (slim) chance that your code doesn't actually have any handlers, and they're all in the C++Builder's runtime (might make it easy if the runtime is a separate DLL).
You should try to convince C++Builder to update their compiler to support SafeSEH. It's been around in the Windows platform since XP SP2, and plugs a pretty nasty security hole (exception handler addresses exist on the stack in x86, just waiting for a buffer overflow to put any random address there to be executed)
For the issue related to /NXCOMPAT and /DYNAMICBASE, I have created a request for the C++ Builder linker to support these flags here: https://quality.embarcadero.com/browse/RSP-13072
Using editbin.exe from Visual C++ is hardly an ideal solution, and their linker needs to support these flags natively.
UPDATE: An additional request has been created here for the C++ Builder / Delphi runtime files (DLLs/BPLs) to be distributed with these flags already set, so as to avoid having to use EDITBIN from Visual C++ to set them yourself: https://quality.embarcadero.com/browse/RSP-13231

FastMM and Dynamically loaded DLLs

I have a host application, that loads a dozen of libraries at start up. I want to switch from Delphi 7s default memory manager to the full version of FastMM4 for better mem leak reporting.
Should I include FastMM4 in the uses section of both the host application and the libraries?
What about shared runtime packages?
Some added information:
We have one exe and >20 dlls. Everyone is sharing a single runtime package.
We do not use sharemem today. Not that I know about. ShareMem is not included in eighter the exe or the dlls that I had a quick look at to day.
Additional questions:
Can I use the same options inside fastmems inc file in all projects, or do the exe and the dll need different settings?
Excerpt from FastMM4options.inc file.
To me it means that if all your packages, dll's and executables are compiled with ShareMM, it should be possible to replace the Delphi 7s default memory manager.
{-----------------------Memory Manager
Sharing
Options------------------------}
{Allow sharing of the memory manager
between a main application and DLLs
that were also compiled with FastMM.
This allows you to pass dynamic arrays
and long strings to DLL functions
provided both are compiled to use
FastMM. Sharing will only work if the
library that is supposed to share the
memory manager was compiled with the
"AttemptToUseSharedMM" option set.
Note that if the main application is
single threaded and the DLL is
multi-threaded that you have to set
the IsMultiThread variable in the main
application to true or it will crash
when a thread contention occurs. Note
that statically linked DLL files are
initialized before the main
application, so the main application
may well end up sharing a statically
loaded DLL's memory manager and not
the other way around. }
{.$define ShareMM}
{Allow sharing of the memory manager
by a DLL with other DLLs (or the main
application if this is a statically
loaded DLL) that were also compiled
with FastMM. Set this option with
care in dynamically loaded DLLs,
because if the DLL that is sharing
its MM is unloaded and any other DLL
is still sharing the MM then the
application will crash. This setting
is only relevant for DLL libraries
and requires ShareMM to also be set to
have any effect. Sharing will only
work if the library that is supposed
to share the memory manager was
compiled with the
"AttemptToUseSharedMM" option set.
Note that if DLLs are statically
linked then they will be initialized
before the main application and
then the DLL will in fact share its MM
with the main application. This
option has no effect unless ShareMM is
also set.}
{.$define ShareMMIfLibrary}
{Define this to attempt to share the
MM of the main application or other
loaded DLLs in the same process that
were compiled with ShareMM set. When
sharing a memory manager, memory
leaks caused by the sharer will not be
freed automatically. Take into
account that statically linked DLLs
are initialized before the main
application, so set the sharing
options accordingly.}
{.$define AttemptToUseSharedMM}
{Define this to enable backward
compatibility for the memory manager
sharing mechanism used by Delphi 2006
and 2007, as well as older FastMM
versions.}
{$define
EnableBackwardCompatibleMMSharing}
What you're looking for is called SimpleShareMem. It's included in the FastMM package. Make sure both your app and your DLLs are using it as well as FastMM4 at the top of their uses clause. That makes sure they all share the same heap instead of using separate ones.
Of course, shared memory is only necessary if you're going to be passing dynamic memory between the app and the libraries, such as strings or objects. If not, then you don't need SimpleShareMem, but I'd still recommend to switch the libraries to FastMM as the memory manager for increased performance and improved stability.
since "Everyone is sharing a single runtime package." I'd recommend the method I'm using. Simply, add FastMM4 to your shared runtime package (Of course, you'll need to put FastMM4 in "using" declaration in each library and host application anyway).
This way has some advantages like:
simple method to switch FullDebugMode on/off [and other options of course]. No project recompilation is needed, recompiling the shared package only is enough to switch the FullDebugMode in the whole application (including dll's) as the FastMM is instanced only once.
no versioning problem. When you update FastMM (which, once used, becomes crucial component of the whole app and plugins) you don't have to ship the whole build (app & plugins) again. Once again, updating the shared package is enough.
no memory manager issues when unloading plugins. I've had some problems with FastMM being uninstalled once the first plugin library was unloaded, thus causing tons of bugs on application shutdown.
no tracking problems - in case of any memory leak or other memory issue you'll be provided with valid call stack, even if the bug occurred in the DLL code.
Here are the (non-standard) options I'm using in my FastMM4Options.inc in order to get the whole thing working as described above.
{$define NeverUninstall}
{$define UseRuntimePackages}
{.$define ShareMM}
well I believe the rest was left unchanged, but if something is wrong, here is the full file:
http://pastebin.4programmers.net/693
Afaik there is sharemm, a version of fastmm to share over DLL bounderies.
If your application is compiled with runtime packages, no additional actions are needed because runtime packages use only one memory manager, always. You just need to specify the memory manager of your choice once, preferably in the main application code as the first unit in the uses list. All the other runtime packages do not require modifications, they'll use the correct memory manager automatically, whatever that memory manager is.
If your app is compiled without runtime packages then every dll has its own memory manager. By default they all use their default memory managers, and if I'm not mistaken, it's a sharing MM, that is, you can transfer strings for example to and from dlls. If you want to replace the default MM with another sharing one, you'll need to include new memory manager as the first unit in the uses list in EVERY dll or exe you want to work together.
The difference is that with runtime packages sharing occurs at the package level. Even non-sharing MM will be shared. Without runtime packages every DLL uses a separate MM, and it's only when those separate memory managers cooperate that you get sharing.
My opinion is that unless your app interacts with dlls really closely (read: has forms and components in dlls), the best approach is not to rely on having sharing memory manager at all, but to manage your memory properly, keeping track of who creates what and deleting objects in the same library where you instantiated them. It's not hard. Just return interfaces instead of objects, return shortstrings (fixed-length) or copy the data into the provided buffer instead of returning strings, and so on. Do not return things that will be freed by the caller, don't accept things that the callee will have to free, and you'll be basically safe. Not only this solves all the possible memory manager problems, it also lets you write dlls in any language.
Ypu have two choices: keep on using the ShareMem unit and the BorldMM.dll replacement you find in the FastMM distribution, or modify both the executable and DLLs to include the FastMM memory manager, by placing the unit as the first one. You should also tailor some of the $DEFINEs you find in FastMM4Options.inc to your needs, they are well explained there. AFAIK run-time packages use the installed memory manager.

F# powerpack and distribution

I need arbitrary precision rational numbers, which I'm given to understand are available in the F# powerpack. My question is about the mechanics of distribution; my program needs to be able to compile and run both on Windows/.Net and Linux/Mono at least, since I have potential users on both platforms. As I understand it, the best procedure is:
Download the powerpack .zip, not the installer.
Copy the DLL into my program directory.
Copy the accompanying license file into my program directory, to make sure everything is above board.
Declare references and go ahead and use the functions I need.
Ship the above files along with my source and binary, and since the DLL uses byte code, it will work fine on any platform.
Is this the correct procedure? Am I missing anything?
You're essentially correct, arbitrary precision rational numbers are available only in PowerPack (BigInteger is part of .NET 4.0, but rationals are still F# specific).
However, you'll also need to distribute your program with F# runtime redistributable (that is the FSharp.Core.dll assembly). It contains some basic F# types (such as types used to represent functions) that are not a part of standard .NET runtime.
More information about F# Redistributable Package is available at MSDN
You can download the FSharp.Core.dll redist from Microsoft Downloads.
When you add a reference to your project, the compiler includes the name and version of the referenced library in your application. When the application starts, the runtime tries to locate the library in various places. So, to deploy your application on both .NET and Mono, you'll need to (somehow) distribute your application together with FSharp.Core.dll and FSharp.PowerPack.dll.
The F# Redistributable and F# PowerPack installers place the library to GAC (Global Assembly Cache) which is shared by all .NET apps on the computer. On Mono, you can get the same result by using the gacutil tool (from command line). In that case, you need to copy them somewhere (anywhere) and run this tool. Your application will find them in the GAC.
Alternatively, if you place the assemblies to the same folder as your application (exe file) then both .NET and Mono should locate them correctly as well and it should work. I believe that this is discouraged for versioning reasons (e.g. the globally installed file can be easily updated), but I don't think the license prohibits this form of deployment.
It seems that for creating .NET/Mono redistributable, using the second technique would be easier (as it allows simple xcopy depoloyment).

Delphi and COM: TLB and maintenance issues

In the company that i work, we develop all the GUI in C#, but the application kernel is mainly developed in Delphi 5 (for historical reasons), with a lot of components made in COM+. Related to this very specific sort of application a I two questions:
Experienced guys in Delphi and/or COM, do you have any workrounds to work with the buggy TLB interface ?
Some of the bugs are: IDE crashing during edition of a large TLB, lost of methods IDs, TLB corruption, etc.
Here, we haven't found any good solution. Actually we tried do upgrade do the new 2007 version. But the new IDE TLB interface has the same bugs that we found before.
How do you control TLBs versions ? The TLB file is in a binary format and conflict resolutions are very hard to do. We tried to do it exporting the interfaces descriptions to IDL and commiting into CVS, but we didn't found any good way to generate TLBs from IDL using Delphi. Additionaly, the MIDL tool provided by Microsoft, didn't parse correctly the IDL files that we exported from delphi.
I think you should have a good look at Delphi 2009.
Delphi 2009 has changes to the COM support, including a text-based replacement for the binary TLB files.
You can read more on Chris Bensen's blog.
In the distant past (before I started working for CodeGear) I gave up on the odd Delphi-ized IDL language that the IDE presented, and wrote my own IDL and compiled it using MS midl. This largely worked; the only catch, IIRC, was making sure dispids (id attribute) were correct on automation interfaces (dispinterfaces) for property getters & setters - there was some invariant that tlibimp expected but midl didn't guarantee.
However, now that Delphi 2009 uses a safe subset of midl syntax, and includes a compiler for this midl in the box and integrated into the IDE, these problems should be a thing of the past.
We have also just installed Delphi 2009 and it does seem to have improved the support for Typelibraries. However I have worked with COM and type libraries for quite some time and here are my general gotchas that I have found over the years. I would agree its pretty buggy and is all the way up to Delphi 2006 (our version prior to using 2009).
Always have every file writeable before opening. This may sound obvious, but when working with source control sometimes we forget to do this and try to remove readonly flag after opening a file - Delphi cant deal with this. Ensure tlb is writable before opening.
If editing a standalone typelibrary you MUST have a project open. For some reason if you open a type library on its own it will not save. Create a blank project and then open your typelibrary. For some reason this allows the type library to be saved.
If your type library is used by an application or COM+ ensure that application is shut down or COM+ disabled before opening the type library. Any open apps will prevent the type library from being saved.
However I think your best solution is probably an upgrade. You get Unicode support too.
Using Delphi 2009 has greatly taken much of the pain out of huge TLB files, and conversion of our existing objects was painless, but our com objects don't use any third party libraries.
We will be migrating our gui applications over once the library vendors release supported versions.
Same experience with the TLB interface here: we simply stopped using it.
We work with several separate IDL files (hand-build) for different parts of our framework, making use of the #include construct to include them into the IDL of the actual application, then generate the single tlb using MIDL and tlibimp it. If the application has no IDL of it's own, pre-compiled version of the different framework TLB files are available.
Whenever the framework enters a new version, a script is run to re-generate the GUIDS on all necessary interfaces in the IDL files.
This has served us well for many years, and for us to move over the new Delphi 2009 IDL/TLB toolset will have to be not only integrated into the IDE, but also versatile when it comes to automated builds and whatnot. Can't wait to get my hands dirty with some experiments!

Resources