undefined reference to `htole32' - c

error occurs while compiling the following c code on CentOS release 4.3.
#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
union {
uint32_t u32;
uint8_t arr[4];
} x;
x.arr[0] = 0x11;
x.arr[1] = 0x22;
x.arr[2] = 0x33;
x.arr[3] = 0x44;
printf("x.u32 = 0x%x\n", x.u32);
printf("htole32(x.u32) = 0x%x\n", htole32(x.u32));
printf("htobe32(x.u32) = 0x%x\n", htobe32(x.u32));
exit(EXIT_SUCCESS);
}
Details of compiling errors:
$ gcc a.c /tmp/ccki8bVg.o(.text+0x3a): In function main': :
undefined reference tohtole32' /tmp/ccki8bVg.o(.text+0x58): In
function main': : undefined reference tohtobe32' collect2: ld
returned 1 exit status
It seems that there isn't htole32 and htobe32 on my server.
$ man htole32
No manual entry for htole32

The manual page actually has:
#define _BSD_SOURCE
before the #include <endian.h>. It only has that in the top section though, not in the example program below. Of course, since your target system doesn't even have the manual page, that might imply it has a runtime environment which doesn't implement this (non-standard) part.

Related

Getting the error code: collect2.exe: error: ld returned 1 exit status

While compiling the C code as follows:
#include <stdio.h> // Notice the library included in the header of this file
#include <stdlib.h>
#include "myLibrary.h" // Notice that myLibrary.h uses different include syntax
#define MAX_LENGTH 21.8
#define WORK_WEEK 5
int main(void) {
function1();
return EXIT_SUCCESS;
}
I am getting the following:
d:/programs/mingw/bin/../lib/gcc/mingw32/8.2.0/../../../../mingw32/bin/ld.exe: C:\Users\svtte\AppData\Local\Temp\ccyHWfzC.o:02_01.c:(.text+0xc): undefined reference to `function1'
collect2.exe: error: ld returned 1 exit status
The myLibrary.h file is as follows:
#ifndef MYLIBRARY_H_
#define MYLIBRARY_H_
void function1(void);
void function2(void);
#endif /* MYLIBRARY_H_ */
and myLibrary.c is as follows:
void function1(void){
puts("It works :)");
}
void function2(void){
//This function does nothing as well
}
Any reasons as to why I am getting the error response would be helpful. Also, any pointers to the possible fixes would be great.
The likelihood is that you’re not including 'myLibrary' when you link to build the executable.

Build against newer linux headers than libc is built using

I want to write a program using the new SCHED_DEADLINE scheduling policy available since Linux 3.14.
I start out with a simple program trying to use the sched_setattr function.
#include <sched.h>
int main(void)
{
// struct sched_attr attr;
// attr.size = sizeof(struct sched_attr);
// attr.sched_policy = SCHED_DEADLINE;
sched_setattr(0, (void*)0, 0);
return 0;
}
However when compiling I get the following error:
$gcc dead.c
dead.c: In function ‘main’:
dead.c:8:2: warning: implicit declaration of function ‘sched_setattr’ [-Wimplicit-function-declaration]
sched_setattr(0, (void*)0, 0);
^~~~~~~~~~~~~
/tmp/ccGxWxZE.o: In function `main':
dead.c:(.text+0x19): undefined reference to `sched_setattr'
collect2: error: ld returned 1 exit status
My system is running Ubuntu 16.10 Yakkety, with kernel 4.8.0-59-generic. The sched.h file included is found in /usr/include/sched.h and is provided by the package libc6-dev. This headerfile does not contain the function sched_setattr and friends that I am trying to use.
However the kernel (and kernel headers) I have installed comes with a sched.h header file containing the definitions I need. It is located at /usr/src/linux-headers-4.8.0-58/include/linux/sched.h, on my system.
So I naively think lets just build against the newer linux headers instead of the libc6-dev provided headers. My program will only run on this or newer kernels, but that is just fine.
I modify the first line to be: #include <linux/sched.h> and execute:
gcc -I/usr/src/linux-headers-$(uname -r)/include -I/usr/src/linux-headers-$(unam -r)/arch/x86/include dead.c
Now I am getting page after page of errors and warning. This does not seem the way to go.
What is the correct way to build a userspace program against a newer Linux headers than those that are provided by libc?
And subsequently how do I build the program above?
sched_setattr() is a syscall and doesn't seem to have one-to-one libc wrapper. You could do the wrapper yourself, something like this:
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <linux/sched.h>
#include <sys/syscall.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size; /* Size of this structure */
uint32_t sched_policy; /* Policy (SCHED_*) */
uint64_t sched_flags; /* Flags */
int32_t sched_nice; /* Nice value (SCHED_OTHER, SCHED_BATCH) */
uint32_t sched_priority; /* Static priority (SCHED_FIFO, SCHED_RR) */
/* Remaining fields are for SCHED_DEADLINE */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
static int sched_setattr (pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall (SYS_sched_setattr, pid, attr, flags);
}
int main (int argc, char *argv[])
{
struct sched_attr attr;
int res;
memset (&attr, 0, sizeof (struct sched_attr));
attr.size = sizeof (struct sched_attr);
res = sched_setattr (getpid (), &attr, 0);
if (res < 0) {
perror ("sched_setattr");
return 1;
}
return 0;
}
Looking at the errors reported when trying to include kernel header files required to get the definition of struct sched_attr and reading the comments found by Googling "kernel headers in user space", I really can't suggest trying to include kernel header files just for this.

Problems calling syscall function in C

For a homework assignment, I have to modify the linux kernel.
I am working on a virtual machine, and I added a system call to the kernel, which I called get_unique_id. Here is the code for get_unique_id.c :
#include <linux/linkage.h>
#include <asm/uaccess.h>
asmlinkage long sys_get_unique_id(int * uuid)
{
// static because we want its state to persist between calls
static int uid = 0;
++uid;
// assign new uid value to user-provided mem location
// returns non-zero if success or -EFAULT otherwise
int ret = put_user(uid, uuid);
return ret;
}
I also added this line to syscalls.h :
asmlinkage long sys_get_unique_id(int * uuid);
This line to syscall_32.tbl :
383 i386 get_unique_id sys_get_unique_id
And finally this line to syscall_64.tbl :
548 common get_unique_id sys_get_unique_id
After recompiling and reloading the kernel, I wrote a little C program to test my system call, here is the code for the C test file :
// get_unique_id_test.c
#include <stdio.h>
#include <limits.h>
#include "syscalls_test.h"
int main(void)
{
// initialize the ints we want
int id1;
int id2;
// check the id's are unique and that no error occured
for (int i = INT_MIN; i < INT_MAX - 1; i += 2) {
long ret1 = get_unique_id(&id1);
long ret2 = get_unique_id(&id2);
if (ret1 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret1);
if (ret2 != 0)
printf("ERROR: get_unique_id returned: %ld\n", ret2);
if (id2 != id1 + 1)
printf("ERROR: successive id's did not increment properly: id1 = %d, id2 = %d\n", id1, id2);
}
return 0;
}
And its header file :
// syscalls_test.h
#include <errno.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#define __NR_get_unique_id 383
inline long get_unique_id(int * uuid)
{
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
}
Unfortunately, while trying to compile the C test file with the following command : gcc -std=c99 get_unique_id_test.c -o get_unique_id_test, I get the following error :
In file included from get_unique_id_test.c:4:0:
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
syscalls_test.h: In function ‘get_unique_id’:
syscalls_test.h:10:5: warning: implicit declaration of function ‘syscall’ [-Wimplicit-function-declaration]
return syscall(__NR_get_unique_id, uuid) ? errno : 0;
^
/tmp/cc1euZ3r.o: In function `main':
get_unique_id_test.c:(.text+0x22): undefined reference to `get_unique_id'
get_unique_id_test.c:(.text+0x34): undefined reference to `get_unique_id'
collect2: error: ld returned 1 exit status
It appears gcc cannot find the function get_unique_id(int * uuid), which is declared in syscalls_test.h, and the syscall function, which should be declared, I believe, in syscall.h, right ?
I don't understand why this happens. Does anybody have an idea ?
EDIT : my problems were solved using a3f's solution (see below) PLUS moving the #include "syscalls_test.h" at the very top of the file, as he said in the comments. Thank you very much.
#define _GNU_SOURCE before including unistd.h or any other header as syscall(2) is not POSIX.
Use static inline instead of plain inline. Plain inline supplies an inline definition, but the compiler is free to ignore it and use the external definition instead, which you aren't providing.
Try the following one:
#include <unistd.h>

When is getdate and strptime not included in time.h?

So the function getdate_r seems to be undefined for me; compiling the following doesn't work in either gcc or clang, (the man page program also doesn't work)
#include <time.h>
int main() {
char timeString[] = "2015/01/01 10:30:50";
struct tm res = {0};
int err = getdate_r(timeString, &res);
return err;
}
clang reports the following
test.c:6:12: warning: implicit declaration of function 'getdate_r' is invalid
in C99 [-Wimplicit-function-declaration]
int err = getdate_r(timeString, &res);
^
1 warning generated.
Other functions from time.h such as getdate, strptime also don't work in a similar manner.
Anyone have an explanation on whats going on?
clang version information
Ubuntu clang version 3.6.0-2ubuntu1 (tags/RELEASE_360/final) (based on LLVM 3.6.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
To make getdate_r available you need to:
#define _GNU_SOURCE 1
before including any include files. Doing so will provide declarations for various GNU extensions including getdate_r:
#define _GNU_SOURCE 1
#include <time.h>
int main(void) {
char timeString[] = "2015/01/01 10:30:50";
struct tm res = {0};
int err = getdate_r(timeString, &res);
return err;
}

Error while referencing into a global variable using multiple files

These are my code files:
header.h
#ifndef HEADER_H
#define HEADER_H
extern int bar;
#endif
foo.c
#include <stdio.h>
#include "header.h"
void foo(void) {
printf("foo: bar = %d\n", bar);
printf("foo: ++bar = %d\n", ++bar);
}
main.c
#include <stdio.h>
#include "header.h"
int main(void) {
int bar=0;
printf("main: bar = %d\n", bar);
printf("main: ++bar = %d\n", bar);
foo();
return 0;
}
When I try to compile those in Ubuntu:
gcc -c foo.c
gcc main.c foo.o -o program
I get this error from the linker:
/tmp/ccWHhwtm.o: In function `foo':
foo.c:(.text+0x6): undefined reference to `bar'
foo.c:(.text+0x1d): undefined reference to `bar'
foo.c:(.text+0x26): undefined reference to `bar'
foo.c:(.text+0x2c): undefined reference to `bar'
collect2: error: ld returned 1 exit status
As I have seen from other answered questions here, in order to share a global variable to multiple files, you will just have to declare the variable in the header file using extern keyword and define it in one of the .c codes.
That is what I have done here, but I get this error.
What is happening ?
bar should be defined in file scope:
#include <stdio.h>
#include "header.h"
int bar=0;
int main(void) {
....
When I was typing: "What is happening", just then, ironically, I figured out the answer :-P.
The problem is that I define the variable inside main function. Thus the definition scope is limited between the braces.

Resources