When using the edk2 (UEFI), functions like memcpy and memset are not available, but they have functions CopyMem and SetMem. Normally that is not too much of a problem, but sometimes the compiler does optimizations that replace my code with memcpy/memset and I get linker errors saying that I have a unresolved reference to them. As far as I can tell, they are used essentially the same (same args and whatnot).
I was wondering what would be possible to fix this rather than individually dealing with the instances as they happen. I tried googling compiler macros, but I couldn't find a good example to see if it would be a good way to do it.
If the compiler inserts memcpy() and memset() as a part of the optimization process, then there's nothing you can achieve using macros. Your chances are:
I. Reduce the optimization level gradually in each individual case until the linker error goes away.
II. Switch to a conforming standard library
III. Implement memcpy() and memset() manually.
If you're using GCC,
You can disable the introduction of memcpy() by using the flag -fno-builtin.
Using the __REDIRECT macro may also work (in sys/cdefs.h) :
__REDIRECT (memcpy, (void *dest, const void *src, size_t n), CopyMem);
As a workaround create forwarding wrappers:
void* memcpy(void *dest, const void *src, size_t n) {
return CopyMem(dest, src, n);
}
Related
In my project, I want to use a non-standard library function, which which may not be defined on certain systems. In my case, it is strlcpy.
From man strcpy:
Some systems (the BSDs, Solaris, and others) provide the following function:
size_t strlcpy(char *dest, const char *src, size_t size);
...
My system does not implement strlcpy, so I rolled my own. All is well, until compiling on a system that already has strlcpy defined: error: conflicting types for strlcpy.
My question: how can I implement a function that may cause naming conflicts down the road? Can I use some directive like #ifdef some_macro(strlcpy), or am I simply left with renaming strlcpy to my_strlcpy?
check if you need to include.
Example - the list of systems will be much longer I think
#if !defined(__FreeBSD__)
#include "mystring.h"
#endif
Would it be better to define the below functions as macro or inline functions? Or is it better to use normal functions and trust the compiler, to maintain (in my opinion) better readability?
typedef unsigned char byte;
void set_size_mark(byte size_mark, byte *ptr)
{
*ptr += size_mark << 1;
}
byte get_size_mark(byte *ptr)
{
return *ptr >> 1;
}
You should inline those. The compiler would almost certainly do this itself anyway.
The code is one line and is unlikely to create code bloat, so it is probably more efficient to inline. The compiler knows this, however, if this is incorrect I think the compiler can ignore the inline keyword.
Generally speaking you should avoid macros - They cause many unexpected problems and are usually just as bad as inline functions while being far harder to use. There are uses for macros, but this is definitely not the appropriate place for one.
You probably should declare these as static inline functions and define them in a header file.
(Alternatively, enable link-time optimization by compiling and linking with gcc -flto -O2, using a recent GCC)
First of all, definitely not macros. Now, we have to choose between:
Never writing inline.
Writing inline sometimes.
GCC in the current version will decide for you whether the function should be inlined or not. So, why bother? That's why I would go for option 1. Shorter code and less time spent by writer(s) and reader(s) of the code.
I have C code with lots of calls strcmp and strcpy that is causing all kinds of problems.
I want to migrate this to strncmp and strncpy but I can not update all the code right now. I want to add compiler warning where ever the functions is used.
The following forces the substitution #define strcmp(x,y) strncmp16(x,y,64) but the problem is still in the code.
Is there a way to add an #warning so that the code still compile but will give a warning for not using the sized functions.
It is a large code base and must compile in four different compilers (GCC, IAR, GHS and VC). It is our own C Library mainly used in embedded systems.
Edit: I am not looking to find all occurrences. There is thousands of tools that can be used to find and replace them. I want there to be a warning so the next time somebody looks at the code they would evaluate and fix the code.
Edit: Strncmp & strncpy have lots of issues and I am very aware of that. I am making an informed decision. These function is in our own C library not just the default functions from the compilers C library.
While you can use #define to force errors, there is no mechanism in the C99 standard (and probably none in C11 either) to force a warning.
If you are using gcc, you can use
__attribute_deprecated__
to mark a prototype as deprecated, e.g.:
int strcmp(const char *, const char *) __attribute_deprecated__;
For Visual Studio:
prefix the function prototype with __declspec(deprecated) as seen in MSDN
You'll need to raise the warning level to 3+.
Example:
#pragma deprecated(strcpy, strcmp)
This line will cause every call to either function to omit a C4995 warning.
These specific functions already emit a C4996 warning but you turn that warning off via a pragma:
#pragma warning(disable: 4996)
I am writing a memory profiler for C and for that am intercepting calls to the malloc, realloc and free functions via malloc_hooks. Unfortunately, these are deprecated because of their poor behavior in multi threaded environments. I could not find a document describing the alternative best practice solution to achieve the same thing, can someone enlighten me?
I've read that a simple #define malloc(s) malloc_hook(s) would do the trick, but that does not work with the system setup I have in mind, because it is too intrusive to the original code base to be suitable for use in a profiling / tracing tool. Having to manually change the original application code is a killer for any decent profiler. Optimally, the solution I am looking for should be enabled or disabled just by linking to an optional shared library. For example, my current setup uses a function declared with __attribute__ ((constructor)) to install the intercepting malloc hooks.
Thanks
After trying some things, I finally managed to figure out how to do this.
First of all, in glibc, malloc is defined as a weak symbol, which means that it can be overwritten by the application or a shared library. Hence, LD_PRELOAD is not necessarily needed. Instead, I implemented the following function in a shared library:
void*
malloc (size_t size)
{
[ ... ]
}
Which gets called by the application instead of glibcs malloc.
Now, to be equivalent to the __malloc_hooks functionality, a couple of things are still missing.
1.) the caller address
In addition to the original parameters to malloc, glibcs __malloc_hooks also provide the address of the calling function, which is actually the return address of where malloc would return to. To achieve the same thing, we can use the __builtin_return_address function that is available in gcc. I have not looked into other compilers, because I am limited to gcc anyway, but if you happen to know how to do such a thing portably, please drop me a comment :)
Our malloc function now looks like this:
void*
malloc (size_t size)
{
void *caller = __builtin_return_address(0);
[ ... ]
}
2.) accessing glibcs malloc from within your hook
As I am limited to glibc in my application, I chose to use __libc_malloc to access the original malloc implementation. Alternatively, dlsym(RTLD_NEXT, "malloc") can be used, but at the possible pitfall that this function uses calloc on its first call, possibly resulting in an infinite loop leading to a segfault.
complete malloc hook
My complete hooking function now looks like this:
extern void *__libc_malloc(size_t size);
int malloc_hook_active = 0;
void*
malloc (size_t size)
{
void *caller = __builtin_return_address(0);
if (malloc_hook_active)
return my_malloc_hook(size, caller);
return __libc_malloc(size);
}
where my_malloc_hook looks like this:
void*
my_malloc_hook (size_t size, void *caller)
{
void *result;
// deactivate hooks for logging
malloc_hook_active = 0;
result = malloc(size);
// do logging
[ ... ]
// reactivate hooks
malloc_hook_active = 1;
return result;
}
Of course, the hooks for calloc, realloc and free work similarly.
dynamic and static linking
With these functions, dynamic linking works out of the box. Linking the .so file containing the malloc hook implementation will result of all calls to malloc from the application and also all library calls to be routed through my hook. Static linking is problematic though. I have not yet wrapped my head around it completely, but in static linking malloc is not a weak symbol, resulting in a multiple definition error at link time.
If you need static linking for whatever reason, for example translating function addresses in 3rd party libraries to code lines via debug symbols, then you can link these 3rd party libs statically while still linking the malloc hooks dynamically, avoiding the multiple definition problem. I have not yet found a better workaround for this, if you know one,feel free to leave me a comment.
Here is a short example:
gcc -o test test.c -lmalloc_hook_library -Wl,-Bstatic -l3rdparty -Wl,-Bdynamic
3rdparty will be linked statically, while malloc_hook_library will be linked dynamically, resulting in the expected behaviour, and addresses of functions in 3rdparty to be translatable via debug symbols in test. Pretty neat, huh?
Conlusion
the techniques above describe a non-deprecated, pretty much equivalent approach to __malloc_hooks, but with a couple of mean limitations:
__builtin_caller_address only works with gcc
__libc_malloc only works with glibc
dlsym(RTLD_NEXT, [...]) is a GNU extension in glibc
the linker flags -Wl,-Bstatic and -Wl,-Bdynamic are specific to the GNU binutils.
In other words, this solution is utterly non-portable and alternative solutions would have to be added if the hooks library were to be ported to a non-GNU operating system.
You can use LD_PRELOAD & dlsym
See "Tips for malloc and free" at http://www.slideshare.net/tetsu.koba/presentations
Just managed to NDK build code containing __malloc_hook.
Looks like it's been re-instated in Android API v28, according to https://android.googlesource.com/platform/bionic/+/master/libc/include/malloc.h, esp:
extern void* (*volatile __malloc_hook)(size_t __byte_count, const void* __caller) __INTRODUCED_IN(28);
Is there a way to check for buffer overflows in VLA's ? I used -fstack-protector-all -Wstack-protector but get these warnings:
warning: not protecting local variables: variable length buffer
Is there a library for achieving this ? (-lefence is for heap memory)
I'm currently using Valgrind and gdb.
You can use -fmudflap instead of -fstack-protector-all
Update: Some documentation and options are here http://gcc.gnu.org/wiki/Mudflap_Pointer_Debugging
Perhaps using alloca() will help. That's annoying, because c99 should save you from having to use it, but the GCC man page seems to say that the stack protection code will be turned on if you use alloca().
Of course the real solution is to write perfect, bug free code that never tries to corrupt the stack.
I don't see how a library could do this for you; with a variable-length array, you're not calling any functions to do the indexing, so there's no place to "hook in" a library. With malloc(), the allocation is explicit in a function and you can track it.
Of course, you could go through the code and use preprocessor trickery to add some macro to each indexing point, and have the macro expand to code that checks the boundaries. But that is very intrusive.
I'm thinking something like changing:
void work(int n)
{
int data[n]; /* Our variable-length array. */
data[0] = 0;
}
into something like:
#include "vla-tracking.h"
void work(int n)
{
VLA_NEW(int, data, n); /* Our variable-length array. */
VLA_SET(data, 0, 0);
}
Then come up with suitable macro definitions (and auxiliary code) to track the accesses. As I said, it won't be pretty. Of course, the idea is that the macros would be able to "compile out" to just the plain definitions, controlled by some build-time setting (debug/release mode, or whatever).