I wrote a module which uses EXPORT_SYMBOL(func) to export the function func.
When modifying the kernel code,
I declared extern void func(); at the top, and called func().
But when compiling kernel, I get undefined reference to 'func' error.
I guess the compiler can't find where func() is, but I don't know how to fix it.
Can someone help me out? Thanks a lot!
Related
Say that I have an object file called test.o. It contains a reference to a function called say. Also say that I have some go code:
func main() {
say()
}
Could I pass in the object file as an argument when compiling my Golang source (go build --include=test.o), or reference it in the Go source?
So the question is: how can I access the function stored in test.o from within my Go code?
So the question is: how can I access the function stored in test.o from within my Go code?
You cannot.
Well, your question is unclear. If you have some C code compiled to some .o you can use cgo and call from go into a .so made from your .o. Read about cgo how to do it.
You can compile go code so that it can be loaded dynamically during runtime. This mechanism is called plugins. All of this is complicated. The best advice is: Stop whatever you are trying and redesign. Your question smells like an XY problem. Go is compiled from source.
So the question is: how can I access the function stored in test.o from within my Go code?
You can.
Take a look at: https://github.com/pkujhd/goloader - note that unless you're just hacking something for your own fun and entertainment, you probably shouldn't.
I'm getting these errors while linking, both messages have to do with the same object file.
CALL16 reloc at 0x5f8 not against global symbol
and
could not read symbols: Bad value
The 2nd message seems to be the reason I'm getting the CALL16 error, but the file compiles just fine.
Any tips on fixing this?
FYI, I'm cross compiling for a MIPS target and using gcc 4.1.2
EDIT: No luck so far:
Here are my flags used:
-fPIC,-Wl,-rpath,-Wl,-O1
I've also tried the following without success:
-mno-explicit-relocs
-mexplicit-relocs
-mlong-calls
-mno-long-calls
-mxgot
-mno-xgot
Meanwhile, I'll go back to the source at this point and investigate more.
Aha!
Thanks to a colleague of mine, we found the issue.
Here was the issue:
There was a forward declaration/prototype of a function.
void FooBarIsBest(void);
Later on in the file the function was defined.
static void FooBarIsBest(void)
{
// do the best
}
The issue here was that in the prototype the keyword static was left out. So it was like a whole new function was being defined.
The CALL16 reference is used by gcc for relocatable code. The assembly code of the file showed that CALL16 was being used on this function... Which is wrong, as this function is local.
Interestingly, this code used to compile & link just fine with an older version of gcc (3.2.2).
Another lessoned learned. :)
Try -mlong-calls flag to the compiler.
Also see the manual for more specific MIPS options.
I have a problem. Requirement for the project is that we cannot link our app with standard library ( so -nostdlib is on in gcc).
my_stdlib.c contains implementation of all functions my_memset, my_memcpy ... but linker needs memcpy to copy structs
MyStruct struct = my_struct;
and is complaining about "undefined reference to `memcpy'", which is of course correct.
Is it possible to remap memcpy to my_memcpy using linker script, parameters passed to ld or other way, so linker can use our implementation to copy structs?
Probably -wrap,function could help but I cannot change my_memcpy to __wrap_memcpy.
At the GCC level, you can redirect the memcpy symbol to a different symbol using:
void *memcpy (void *, const void *, size_t) __asm__ ("my_memcpy");
This will apply to internally-generated memcpy calls, too. (With GCC. I think it does not change the internal call sites with Clang.)
compile with -fno-builtin. This should avoid it.
I have been using cgo to interface between Go and C. However, when trying to do the same for Go and C++, I get a compile error every time I attempt to call a function. Using go build . from the code's directory, I get the following errors:
./main.go: In function 'void _cgo_3612c872201c_Cfunc_getint(void*)':
./main.go:48:53: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
./main.go:54:4: error: invalid conversion from 'void*' to '_cgo_3612c872201c_Cfunc_getint(void*)::<anonymous struct>*' [-fpermissive]
I've put a super simple example below which shows the problem.
main.go:
package main
/*
#cgo CFLAGS: -x c++
int getint()
{
return 1;
}
*/
import "C"
import (
"fmt"
)
func main() {
fmt.Println(C.getint())
}
Does anyone know if this is a bug in cgo, or something wrong with how I wrote the code? According to the cgo documentation, C++ is supported. I'm using Go version 1.7.5 for linux/amd64.
Thanks so much!
I may be wrong, but I think cgo supports C++ only in the sense it knows how to invoke a C++ compiler on the non-Go files which looks like containing C++ source code, and that's all.
The problem is that C++ compilers use so-called "mangling" for the symbols made exported from the compiled files. Exporting symbols were originally
intended only for C-like languages, where all which can be exported are plain
functions and variables, but C++ adds classes and function overloading,
and to export such symbols from compiled ("object") files, a C++ compiler
needs to "mangle" them using certain schema to encode names of classes
and types of arguments in these names. What's worse, each C++ compiler
brand uses its own mangling schemas.
So I think while cgo is able to compile C++ code, it sort of assumes that
all the symbols exported (to be used by Go) in your C++ files are
wrapped in extern "C" { ... } (see this).
If you need calls to "native" C++ exported stuff, you'd need to use
SWIG I reckon.
I am trying to create a dylib in xcode. I can able to create dylb by choosing c/c++ Library template in Xcode.
I want to add "init" method for this dylib. I don't know how to add "init" method for dylib.
My idea is to call this "init" on runtime with the help of dlopen().
Thanks for your valuable feedback.
If you code in C++, you could have static objects in your dlopen-ed library; their constructors get called at dlopen time (and their destructor is running at dlclose time).
If your code is compiled by gcc (be it in C, or in C++, or perhaps even some other languages) you could use the constructor and destructor function attributes
(You could use the obsolete symbols _init and _fini but this is an obsolete feature of dlopen (at least on Linux, and probably on MacOSX). Then you would have to declare them extern "C" void _init(void); in C++.)
Don't forget that dlsym deals with unmangled names, so you want to declare extern "C" the C++ names for it.
You could also have your own convention that your dynamically loaded things should have, for example, a function named my_initialization and your code doing the dlopen would later use dlsym to find it. You should have documented conventions on what symbols are dlsym-ed and how they are used.
I don't know well MacOSX, but I googled this documentation