importing a specific symbol from module in LLVM - llvm

I would like to know if there's any way to import only specific symbol in LLVM.
Take a look at this javascript example in node:
import mySymbol from 'some/path.mylang'
I've already seen this post on stackoverflow: LLVM ir how to import other modules?
but it really isn't exactly what I'm looking for.
If LLVM doesn't allow to import only specific symbols from a module, then how can I implement this? Maybe string manipulation and regex on generated .ll files and concatenating them?

Use llvm-extract to produce a module that contains only the symbol you want, then llvm-link against that?
Normally an LLVM module must have a list of all symbols it's going to import anyways, but in this case "import" means "that this modules uses but are defined by some other Module". That doesn't seem to be what you mean by import?
If you mean that you want to clone a function into your module using the C++ API just call CloneFunction on that one function you want to copy into your other module?

Related

C++20 modules: are path-relative imports a thing?

I know you can export modules like that in C++20:
export module modulename;
And import later as
import modulename;
But can you use filesystem paths in the module system somehow? Something like
import "./modulename.ixx"
I'm using MSVC 19.30.30528 (2022 preview).
Module names are supposed to uniquely identify the module in question. So there are no provisions for specifying "ixx" or any other files. You say what the module name is, and your build system goes looking for modules matching that name. Period.
Importing a quoted string means that you are doing a header unit import. That means it will read the file in question much like you had done a #include and dump all of its symbols into your source file. The difference is that it effectively creates a module in so doing, such that if several files import the same header unit, the system doesn't need to recompile the header unit for each file that imports it.

C++20 modules - how to get their file names?

My aim is to build a simple c++ parser which collects the name of every struct / class in a c++ program.
The problem is concerning c++20 modules. Consider the following code:
import module-name;
How can my parser know where the module originated from and collect the name of structs /classes?
Had it been an #include directive my parser would just parse the given file name...
Is there any way to get the relevant file names for a given module?
The module files loaded by the compiler are all previously generated by the compiler. The compiler gives those files some name likely based on the module's given name. Exactly how that works is up to the compiler and build environment, and will likely vary among compilers.
Basically, it's not really your job. When you generate a module, you get some output files from the build system, just as you would a library or DLL. You then make those available to later builds that want to consume them, telling the compiler where it can find those module files.

Ruby FFI not finding certain functions?

I'm trying to use Ruby's FFI library to link functions from the bitcoin-core secp256k1 library.
To make the secp256k1_ecdsa_sign function accessible, I built libsecp256k1 using autotools (as directed in README.md). Then I created a shared object to use in FFI by running g++ -shared secp256k1/src/.libs/libsecp256k1_la-secp256k1.o. Importing this into my Ruby file using FFI let me use the function and everything worked perfectly.
I'm trying to do the exact same with the secp256k1_ecdsa_sign_recoverable function, which is in the same C project, just a different header file. However, I get the error Function 'secp256k1_ecdsa_sign_recoverable' not found in [bin/secp256k1.so] (FFI::NotFoundError).
I think this is either because I'm not creating the shared object properly (created with the aforementioned g++ command), or because this function is for some reason not a public-facing one in the C project (though I don't know enough about C to know how to figure out if this is the case).
If someone could help me figure out how to use this function it would be greatly appreciated.
It ends up the secp256k1_recovery.h file is only included if you specify that when building the libsecp256k1 library. Specifically, I needed to run ./configure --enable-module-recovery instead of ./configure.

About shared library in Linux, is there a way to select export functions in a library?

I read the tutorial here:
http://www.techytalk.info/c-cplusplus-library-programming-on-linux-part-two-dynamic-libraries/
It looks to me there is no functionality like dllexport of DLL in Windows platform.
Is there some way to select certain functions within the library as export function and make the rest functions in the library remain invisible to external call?
You may want to use the visibility function attribute of GCC.
See GCC visibility wikipage and read Drepper's paper How To Write Shared Libraries
There are multiple ways to do this.
Either use the visibility function attribute as mentioned in Basiles answer or use a linker version script to do the job.
In a linker script you list all the functions that you want to export. Here is an example:
File: MyLinkerScript.exp
{
global:
myExportedFunction1;
myExportedFunction2;
myExportedFunction3;
local: *;
};
During the link step of your shared library you just pass the following extra parameters to gcc:
-Wl,--version-script=MyLinkerScript.exp
Afterwards all symbols in the shared library will be private except for those listed in the global section of your version script.

Hide export symbols without using a DEF file

I would like to hide exported symbols from a DLL for obfuscation purposes.
That is pretty neatly doable when using a module definition file (.def) looking something like this;
EXPORTS
??0Foo#QAE#XZ #1 NONAME
??1Foo#QAE#XZ #2 NONAME
?Bar#Foo#UAEHXZ #3 NONAME
Trouble is, such solution is highly inflexible and demands manual work. As you can see within my example, I am exporting C++ symbols, hence they are heavily decorated by my compiler.
So my current workflow looks like this;
I have to first create a version of my DLL that exports all symbols in the standard way using __declspec(dllexport), then I need to extract all exported symbol names using dumpbin or alike. After that is done, I need to copy&paste the symbols into my module definition file and add that NONAME directive. Then I have to make sure that my original sources do not use that __declspec(dllexport) anymore. Once all of that is done, I need to activate that .def file within the project settings and then I can finally build the export symbol free version of that DLL. Plenty of work for that rather simple task, I guess.
Before covering all of this using a bunch of scripts and stuff, I thought that maybe, just maybe there is a solution that is much simpler?
Please note that I am using VisualStudio (2012) and hence that nifty GCC pragma hidden wont do, as far as I know.