zydis icon indicating copy to clipboard operation
zydis copied to clipboard

Document how to use no-libc mode

Open athre0z opened this issue 2 years ago • 6 comments

We prominently advertise no-libc support but don't provide any instructions on how to actually use it. We should add a small section explaining this to the README.

Essentially:

  • paste both zycore and zydis headers and sources into your project (since users will most likely not be using CMake for no-libc builds)
  • manually create ZydisExportConfig.h and ZycoreExportConfig.h headers that would otherwise be created by CMake, or reuse the ones from the msvc project.
  • define ZYAN_NO_LIBC via compiler flags.

We should also discourage doing ZYAN_NO_LIBC when libc is present, since it results in a pretty significant performance hit (because our implementations of memset and friends are extremely minimal and much less optimized than the typical libc variant.

athre0z avatar Oct 29 '21 17:10 athre0z

Would it make sense to have a mode like ZYAN_NO_LIBC that still depends on memset and friends being provided by the user?

bjorn3 avatar Oct 29 '21 17:10 bjorn3

Would it make sense to have a mode like ZYAN_NO_LIBC that still depends on memset and friends being provided by the user?

That's essentially what you have to do when enabling the NO_LIBC flag. For some functions we ship very simple replacements, but obviously not for things like malloc and so on.

Internally we are using macros like ZYAN_MALLOC which can be provided by the user. The simple replacement stubs can be overwritten as well.

flobernd avatar Oct 29 '21 17:10 flobernd

I think what @bjorn3 is suggesting here is the ability for users to replace the set of performance-critical functions among the functions that we substitute in ZYAN_NO_LIBC builds with fast custom implementations.

athre0z avatar Oct 29 '21 17:10 athre0z

Yes yes, that should already be possible if I remember correctly.

Edit: ... by defining the ZYAN_CUSTOM_LIBC macro.

flobernd avatar Oct 29 '21 17:10 flobernd

Yeah, we allow users to specify ZYAN_CUSTOM_LIBC. It is however pretty cumbersome to use, because you have to implement all the macros that we define, which is .. quite a few. As a simpler alternative, we could rename our functions from e.g. ZYAN_MEMCPY -> ZyanMemCpy, adding macros for them that do ifndef:

#ifndef ZYAN_MEMSET
#  define ZYAN_MEMSET ZyanMemset
#endif

This would allow users to pass -DZYAN_MEMSET=MyCustomMemset to replace just a few of the functions. memset, memmov and memcpy are probably going to be the prime candidates for eating CPU cycles in practice, so doing this just for these three would probably already suffice.

Then again, given how rare I expect this use-case to be, the existing solution might be already be sufficient and adding the additional complexity might not be worth it.

athre0z avatar Oct 29 '21 17:10 athre0z

In any case, this is a welcome reminder that we should also document ZYAN_CUSTOM_LIBC in the same section. I would've totally forgotten about that otherwise!

athre0z avatar Oct 29 '21 18:10 athre0z