Error while implementing hello world system call in Lunix - c

I am compiling my kernel for my hello world system call but getting following error:
ld: arch/x86/entry/syscall_64.o:(.rodata+0xdc0): undefined reference to __x64_sys_hello' ld: arch/x86/entry/syscall_x32.o:(.rodata+0xdc0): undefined reference to __x64_sys_hello' make: *** [Makefile:1139: vmlinux] Error 1 site:stackoverflow.com
Following are the changes i made to add my hello world system call:
Current kernel version=5.11.0.40
linux-5.8.1/hello/hello.c:
#include <linux/kernel.h>
#include <linux/syscalls.h>
asmlinkage long sys_hello(void)
{
printk("Hello world\n");
return 0;
}
linux-5.8.1/Makefile:
ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/ hello/
linux-5.8.1/include/linux$ gedit syscalls.h
asmlinkage long sys_hello(void);
linux-5.8.1/arch/x86/entry/syscalls$ gedit syscall_64.tbl
440 common hello sys_hello
Looking forward for your responses.Thanks in advance.

This code:
asmlinkage long sys_hello(void)
{
printk("Hello world\n");
return 0;
}
needs to be changed to:
SYSCALL_DEFINE0(hello)
{
printk("Hello world\n");
return 0;
}
The SYSCALL_DEFINE0(sname) macro is defined by #include <linux/syscalls.h>. It is defined differently depending on whether CONFIG_ARCH_HAS_SYSCALL_WRAPPER is defined in the kernel config. It is defined for some architectures, but not for others.

Related

Undefined symbol "_clone" on OS X

Code:
#include <stdio.h>
#include <sched.h>
#include <stdlib.h>
#include <sys/wait.h>
#define _GNU_SOURCE
void *stack_memory()
{
const int stackSize = 65536;
void* stack = (void*)malloc(stackSize);
if (stack == NULL) {
printf("%s\n", "Cannot allocate memory \n");
exit(EXIT_FAILURE);
}
return stack;
}
int jail(void *args)
{
printf("Hello !! - child \n");
return EXIT_SUCCESS;
}
int main()
{
printf("%s\n", "Hello, world! - parent");
clone(jail, stack_memory(), SIGCHLD, 0);
return EXIT_SUCCESS;
}
Error:
Undefined symbols for architecture x86_64: "_clone", referenced
from:
_main in docker-4f3ae8.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code
1 (use -v to see invocation)
Linux doesn't prefix symbols with a leading _ so you're not using Linux.
But the clone(2) system call is Linux-specific, according to its man page.
clone() is Linux-specific and should not be used in programs intended
to be portable.
Probably you're using OS X or something. And you're compiling as C, so calling an un-declared function isn't a compile-time error (just a big warning). This is why it's a linker error instead of a compile-time error (and you ignored compiler warnings.)
And BTW, #define _GNU_SOURCE after including header files is pointless. You have to define feature-request macros before including headers to get them to define prototypes for GNU-only functions in cases where that's not already the default.

Share global variable between .c file

Hi I just wondering how to Share global variable between .c file.
I try to add follow code, but still get error.
test.c file
#include <stdio.h>
int max = 50;
int main()
{
printf("max %d", max); // result max 50
}
pass.h
extern int max;
passed.c
#include <stdio.h>
#include "pass.h"
max;
int main()
{
printf("pass %d \n", max);
return 0;
}
But when I compile passed.c I get follow error
Undefined symbols for architecture x86_64:
"_max", referenced from:
_main in passed-iOMugx.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Can anyone help? Thank you so much.
You can declare the variable in a header file, e.g. let's say in declareGlobal.h-
//declareGlobal.h
extern int max;
Then you should define the variable in one and only file, e.g. let's say, test.c. Remember to include the header file where the variable was declared, e.g. in this case, declareGlobal.c
//test.c
#include "declareGlobal.h"
int max = 50;
You can then use this variable in any file- just remember to include the header file where it's declared (i.e. declareGlobal.c), for example, if you want to use it in passed.c, you can do the following:
//passed.c
#include <stdio.h>
#include "declareGlobal.h"
#include "test.c"
int main()
{
printf("pass %d \n", max);
return 0;
}
The problem is that you have two programs, and data (like variables) can not be shared that simply between programs.
You might want to read about shared memory and other inter-process communication methods.
If on the other hand you only want to have one program, and use a variable defined in another file, you still are doing it wrong. You can only have one main function in a single program, so remove the main function from one of the source files. Also in pass.c the expression max; does nothing and you don't need it.
Then pass both files when compiling, like
$ clang -Wall -g test.c pass.c -o my_program
After the above command, you will (hopefully) have an executable program named my_program.

C Beginner: Can't use delay() in a simple C program

test1.c
#include <stdio.h>
int main(void) {
printf("test\n");
delay(1000);
printf("test2\n");
}
When I try to compile...
gcc test1.c -o test1
Undefined symbols for architecture x86_64:
"_delay", referenced from:
_main in ccUnw3tY.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
Certainly there is a lesson here in knowing your libraries and what linking is etc... What am I missing? I am trying to do this on OSX.
There's no delay function in C, you have to use sleep or usleep depending on what OS you're on.
What make you think there is a delay function. I dont see one in the osx docs. There is a sleep function
https://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/sleep.3.html
An alternative of delay in C for unix os is the sleep function :
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/sleep.3.html
do something like :
#include <stdio.h>
#include <unistd.h>
int main(void) {
printf("test\n");
usleep(1000);
printf("test2\n");
}
If you value is for 1000 microsecondes.
The delay function works in Borland C compiler. You have to use the dos.h header file in order to use delay. Some other compilers like MinGW may not support this.

Kernel Module Init and Exit functions being called in wrong order

I'm making a very simple hello world kernel module and getting some crazy behavior. This worked until I upgraded to kernel 3.3.8 and now it... Well, it's calling the init function on exit, and the exit function on initialize. I've made sure my names are correct
// Needed for module definitions
#include <linux/module.h>
// Needed for initilization modules
#include <linux/init.h>
// Must declare some license
MODULE_LICENSE("Dual BSD/GPL");
// Function to be called on insmod
// Returns 0 on success
static int __init mymod_init(void)
{
// Prints kernel alert. Check /var/log/syslog
printk(KERN_ALERT "Module was loaded, this is the printk.");
return 0;
}
// Function to be called on rmmod
static void __exit mymod_exit(void)
{
// Prints kernel alert. Check /var/log/syslog
printk(KERN_ALERT "Module was unloaded, this is the printk");
}
// Register these functions
module_init(mymod_init);
module_exit(mymod_exit);
Sample output:
root#cop4610:/home/cop4610/Downloads/linux-3.3.8/mymodule# insmod
mymodule.ko root#cop4610:/home/cop4610/Downloads/linux-3.3.8/mymodule#
tail /var/log/syslog Oct 12 10:08:20 cop4610 kernel: [ 633.567832]
Module was unloaded, this is the printk
The following is a video of this happening live:
http://www.youtube.com/watch?v=8aJNSpCd7as&feature=youtu.be
It needed a newline!!!!!! Arrggg!!!
printk(KERN_ALERT "Module was unloaded, this is the printk\n");
and
printk(KERN_ALERT "Module was loaded, this is the printk\n");
It seems it wasn't really doing them out of order, it just appeared to, because the first one was not showing up until the second one was issued as the buffer was not flushed.
This is my basic example:
#include <linux/module.h>
#include <linux/kernel.h>
#define MODULE_NAME "hello_md"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("B3h3m0th");
MODULE_DESCRIPTION("Basic LKM; hello world module");
MODULE_VERSION("0.0");
static int __init insert_mod(void)
{
printk(KERN_ALERT "[%s] Init: \"Hello World\"\n", MODULE_NAME);
return 0;
}
static void __exit remove_mod(void)
{
printk(KERN_ALERT "[%s] Exit\n", MODULE_NAME);
}
module_init(insert_mod);
module_exit(remove_mod);
My basic Makefile:
obj-m += basic_module.o
KERNELVERSION = $(shell uname -r)
all:
$(MAKE) -C /lib/modules/$(KERNELVERSION)/build M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(KERNELVERSION)/build M=$(PWD) clean

C - Undefined symbols for architecture x86_64 when compiling on Mac OSX Lion

I'm getting some problems on compiling a very very simple name.c file on Mac OSX Lion.
Now, I started following Harvard CS50 course on cs50.net. I'm not totally new to programming but I was curious on how this course has been taught.
This is the source of name.c:
#include <stdio.h>
#include <cs50.h>
int
main(void)
{
printf("State your name:\n");
string name = GetString();
printf("O hai, %s!\n", name);
return 0;
}
As you can see, it requires this library: https://manual.cs50.net/CS50_Library.
Now, when I compile it, this happens:
Undefined symbols for architecture x86_64:
"_GetString", referenced from:
_main in name-vAxcar.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [name] Error 1
If I use the same GetString() cs50.c function inside my source file, it works perfectly:
#include <stdio.h>
#include <string.h>
#include <float.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
typedef char *string;
string GetString(void);
int
main(void)
{
printf("State your name:\n");
string name = GetString();
printf("O hai, %s!\n", name);
}
string
GetString(void)
{
// CODE
}
Why does this happen?
I installed the library as it says on the link above; I checked and both cs50.h and libcs50.a are respectively in /usr/local/include and /usr/local/lib.
Thank you in advance for your help.
The problem you encounter is in the linking stage, not compiling. You did not provide the implementation of GetString, only its declaration (through the .h file you #include).
To provide the implementation itself, you usually need to link against the library which includes it; this is usually done by the -l flag to g++. For example,
g++ file.cpp -lcs50
Your second sample code does link, because you manually (and explicitly) provide an implementation for GetString, though an empty one.

Resources