implementation of __udivdi3 function - c

I have llvm compiler that supports Riscv vector intrinsic coding and a core on FPGA that is RV32IMV... I have written a C code for the core but when I compile it I get the following error:
error: undefined symbol: __udivdi3
I think it is because I don't have the necessary library added to my linker file for this purpose
but after I searched for the error I found this:
Undefined reference to '__divdi3'
At the end of this post, the author says:
Alternatively, you could write your own implementations of those
functions, or crib the source from GCC, but I don't see why you would
prefer either of those options.
Can anyone suggest a piece of code that implements this function so that I can add it to my code?
I have already added this pices of code for memcpy and it works fine:
void* memcpy(void* dest, const void* src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
((char*)dest)[i] = ((char*)src)[i];
}
}

Related

Cannot execute standalone webassembly file with wasmer

I wrote a matrix multiplication program in C and compiled it using Emscripten with the following command
emcc matrix.c -o matrix.wasm -s STANDALONE_WASM
And the C program is as follows,
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
int matrix() {
int a[101][101];
int b[101][101];
int r[101][101];
for(int i = 0; i<101; i++) {
for(int j = 0; j<101; j++) {
a[i][j] = rand()%1000+1;
b[i][j] = rand()%1000+1;
}
}
for(int i = 0; i<101; i++) {
for(int j = 0; j<101; j++) {
r[i][j] = 0;
for(int k = 0; k<101; k++) {
r[i][j] += a[i][k] * b[k][j];
}
}
}
return 0;
}
int main(){
clock_t start, finish;
double duration;
start = clock();
matrix();
finish = clock();
duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf("computing duration: %fs\n", duration);
return 0;
}
Then I used wasmer to directly run this webassembly file:
wasmer matrix.wasm.
It returned the expected result. Then I wanted to execute this file with a specific function, that is the export function in webassembly file.
I used wasm2wat to translate this executable file into a wat file.Then I found (export "_start" (func 6)). By the way, I did not found any code about export the matrix function. Then I executed the matrix.wasm with the command:
wasmer matrix.wasm -i _start
However, the error appeared. It said:
error: failed to run `matrix.wasm`
╰─> 1: Error while importing "wasi_snapshot_preview1"."clock_time_get": unknown import. Expected Function(FunctionType { params: [I32, I64, I32], results: [I32] })
Then I tried Rust to write a simple program, which just contained a main function and a add function. I used cargo to compile it to two kinds of targets, which is wasm32-unknown-unknown and wasm32-wasi. I compiled them into wat file. This time I found (export "add" (func $add.command_export)). When I executed the wasm32-wasi programm with
wasmer add.wasm -i add
There was also errors appearing. It said:
error: failed to run `hello.wasm`
╰─> 1: Error while importing "wasi_snapshot_preview1"."args_get": unknown import. Expected Function(FunctionType { params: [I32, I32], results: [I32] })
I could execute the file whose target was wasm32-unknown-unknown correctly but I could not use lib function in this kind of target.
I think there are something wrong with my wasm32-wasi file but I do not know why it is and how to deal with it. Could you please tell me how I can call an export function in wasm32-wasi file and how I can call a lib function in wasm32-unknown-unknown file. Also I have some questions about why I use Emscripten compile the C file but the matrix function does not export in wat file. Thank you!
Compilers will often inline functions and remove code that isn't used, this is why your C program ends up with everything inside a _start function. As explained in the FAQ you may list functions to export using emcc -s EXPORTED_FUNCTIONS=_main,_matrix in order to prevent them from being inlined or removed. Adding this results in a wasm module with the function correctly exported.
As for running functions directly, the source code for wasmer run has logic to determine which runtime environment should be exposed to the module. However, if you pass -i function, it entirely skips the environment setup and runs your function directly. In this case, the modules fails to initialize because it imports functions from WASI (in order to write things to the console, and get the current clock time).
I believe the reason why wasm32-unknown-unknown works is that it doesn't link to any runtime, and implements dummy interfaces for things that it can't simulate (all filesystem calls result in errors, etc.)
In summary, wasmer run -i function isn't meant to run functions from modules that have imports, it might be possible to patch wasmer-cli for that, but I'm not sure if it would work across all runtime environments.

undefined reference to `memcpy' error caused by ld

I was developing an embedded project an was struggling to compile it because of this error:
mipsel-linux-gnu-ld: main.o: in function 'fooBar':main.c:(.text+0x3ec): undefined reference to 'memcpy'
This error is caused by every operation similar to this, in which I assign the value of a pointer to a non-pointer type variable.
int a = 0;
int *ap = &a;
int c = *ap; //this causes the error
Here's another example:
state_t *exceptionState = (unsigned int) 0x0FFFF000;
currentProcess->cpu_state = *exceptionState; //this causes the error
I have already included the flag -nostdlib in the makefile...
Thank you in advance!
I have already included the flag -nostdlib in the makefile...
Take that flag out. It blocks linkage to standard library calls. The compiler might actually generate references to the memcpy function, even if your code doesn't explicitly call it.
If you absolutely need -nostdlib, I suppose you could define your own version of memcpy - if that's the only function the linker is complaining about. It won't be as optimized, but it would work. add the following code to the bottom of one of your source files:
void *memcpy(void *dest, const void *src, size_t n)
{
for (size_t i = 0; i < n; i++)
{
((char*)dest)[i] = ((char*)src)[i];
}
}
The fact that you have included -nostdlib is what's causing your problem.
If you copy a structure the compiler may call the standard C runtime function memcpy() to do it. If you link with -nostdlib then you're telling the linker to not include the standard C runtime library.
If you have to use -nostdlib then you'll have to provide your own implementation of memcpy().

MKL BLAS functions not behaving as expected

I can't get Intel MKL to work as it should from C.
I have the following test program:
#include "stdafx.h"
#include"mkl.h"
int main()
{
int one = 1;
int ten = 10;
double copy[10];
double threes[10];
for (int i = 0; i < 10; ++i) threes[i] = 3;
dcopy(&ten, threes, &one, copy, &one);
double l1norm;
l1norm = dasum(&ten, threes, &one);
return 0;
}
which is building and linking fine but not doing what I intended. Specifically at the return line the array "copy" continues to be full of what was there when it was declared and l1norm equal to 0.
I am linking to the libraries : mkl_blas95_ilp64.lib, mkl_core_dll.lib, mkl_intel_ilp64_dll.lib and mkl_intel_thread_dll.lib.
I'm also getting similar problems when running third-party code that calls MKL so I assume the problem is how I have the build configured (in Visual Studio 2015).
The equivalent Fortran program runs fine.
Please check the libraries you link when porting from Fortran to C/C++. MKL requires different libraries and compiling flags with different compilers and settings. At least mkl_blas95_ilp64.lib is not required with C compiler.
Also ILP64 is not common compared to the default model LP64.
MKL Link Line Advisor is a tool provided by Intel to solve this issue. You could use it to check if your libraries and compiling flags are correct.
https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor

Compile a program using mhash

I am trying to use lessfs and learning how it uses mhash to produce its cryptographic fingerprints, so I am taking a look at mhash to see how it handles the hashing algorithms, so I am trying to run some of the examples provided in the program, but I am running into complications and errors
The Mhash example that I was trying to solve is found here: http://mhash.sourceforge.net/mhash.3.html (or below)
#include <mhash.h>
#include <stdio.h>
int main()
{
char password[] = "Jefe";
int keylen = 4;
char data[] = "what do ya want for nothing?";
int datalen = 28;
MHASH td;
unsigned char *mac;
int j;
td = mhash_hmac_init(MHASH_MD5, password, keylen,
mhash_get_hash_pblock(MHASH_MD5));
mhash(td, data, datalen);
mac = mhash_hmac_end(td);
/*
* The output should be 0x750c783e6ab0b503eaa86e310a5db738
* according to RFC 2104.
*/
printf("0x");
for (j = 0; j < mhash_get_block_size(MHASH_MD5); j++) {
printf("%.2x", mac[j]);
}
printf("\n");
exit(0);
}
But I get the following errors:
mhash.c.text+0x6c): undefined reference to `mhash_get_hash_pblock'
mhash.c.text+0x82): undefined reference to `mhash_hmac_init'
mhash.c.text+0x9c): undefined reference to `mhash'
mhash.c.text+0xa8): undefined reference to `mhash_hmac_end'
mhash.c.text+0xf9): undefined reference to `mhash_get_block_size'
collect2: error: ld returned 1 exit status
This is a linker error — ld is the linker program on Unix systems. The linker is complaining because you're using library functions (mhash_get_hash_pblock, etc.) but you didn't provide a definition for them.
The preprocessor directive #include <mhash.h> declares functions (and types, etc.) from the mhash library. That's good enough to compile your program (produce a .o file) but not to link it (to produce an executable): you also need to define these functions.
Add -lmhash at the end of your compilation command line. This instructs the linker that it can look for functions in the library libmhash.a on its search path; at run time, the functions will be loaded from libmhash.so on the search path. Note that libraries must come on the command line after they're used: the linker builds up a link of required functions, which need to be provided by a subsequent argument.
gcc -o myprogram myprogram.c -lmhash

Overriding C library functions, calling original

I am a bit puzzled on how and why this code works as it does. I have not actually encountered this in any project I've worked on, and I have not even thought of doing it myself.
override_getline.c:
#include <stdio.h>
#define OVERRIDE_GETLINE
#ifdef OVERRIDE_GETLINE
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
printf("getline &lineptr=%p &n=%p &stream=%p\n", lineptr, n, stream);
return -1; // note: errno has undefined value
}
#endif
main.c:
#include <stdio.h>
int main()
{
char *buf = NULL;
size_t len = 0;
printf("Hello World! %zd\n", getline(&buf, &len, stdin));
return 0;
}
And finally, example compile and run command:
gcc main.c override_getline.c && ./a.out
With the OVERRIDE_GETLINE define, the custom function gets called, and if it is commented out, normal library function gets called, and both work as expected.
Questions
What is the correct term for this? "Overriding", "shadowing", something else?
Is this gcc-specific, or POSIX, or ANSI C, or even undefined in all?
Does it make any difference if function is ANSI C function or (like here) a POSIX function?
Where does the overriding function get called? By other .o files in the same linking, at least, and I presume .a files added to link command too. How about static or dynamic libs added with -l command line option of linker?
If it is possible, how do I call the library version of getline from the overriden getline?
The linker will search the files you provide on the command line first for symbols, before it searches in libraries. This means that as soon as it sees that getline has been defined, it will no longer look for another getline symbol. This is how linkers works on all platforms.
This of course has implications for your fifth point, in that there is no possibility to call the "original" getline, as your function is the original from the point of view of the linker.
For the fifth point, you may want to look at e.g. this old answer.
There's no standard way to have two functions of the same name in your program, but with some UNIX-like implementations (notably GNU libc) you might be able to get away with this:
#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
ssize_t getline(char **lineptr, size_t *n, FILE *stream)
{
ssize_t (*realfunc)(char**, size_t *, FILE*) =
(ssize_t(*)(char**, size_t *, FILE*))(dlsym (RTLD_NEXT, "getline"));
return realfunc(lineptr, n, stream);
}
You will need to link with -ldl for this.
What is happening here is that you are relying on the behaviour of the linker. The linker finds your implementation of getline before it sees the version in the standard library, so it links to your routine. So in effect you are overriding the function via the mechanism of link order. Of course other linkers may behave differently, and I believe the gcc linker may even complain about duplicate symbols if you specify appropriate command line switches.
In order to be able to call both your custom routine and the library routine you would typically resort to macros, e.g.
#ifdef OVERRIDE_GETLINE
#define GETLINE(l, n, s) my_getline(l, n, s)
#else
#define GETLINE(l, n, s) getline(l, n, s)
#endif
#ifdef OVERRIDE_GETLINE
ssize_t my_getline(char **lineptr, size_t *n, FILE *stream)
{
// ...
return getline(lineptr, n, stream);
}
#endif
Note that this requires your code to call getline as GETLINE, which is rather ugly.
What you see is expected behaviour if you linking with shared libraries. Linker will just assign it to your function, as it was first. It will also be correctly called from any other external libraries functions, - because linker will make your function exportable when it will scan linking libraries.
But - if you, say, have no external libraries that links to your function (so it isn't marked exportable, and isn't inserted to symbol table), and then dlopen() some library that want to use it during runtime - it will not find required function. Furthermore, if you first dlopen(RTLD_NOW|RTLD_GLOBAL) original library, every subsequent dlopen()'d library will use this library code, not yours. Your code (or any libraries that you've linked with during compilation phase, not runtime) will still stick with your function, no matter what.

Resources