I am trying to compile the following eBPF code,
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
SEC("kprobe/do_sys_openat2")
int kprobe__do_sys_openat2(struct pt_regs *ctx)
{
char file_name[256];
bpf_probe_read(file_name, sizeof(file_name), PT_REGS_PARM2(ctx));
char fmt[] = "open file %s\n.";
bpf_trace_printk(fmt, sizeof(fmt), &file_name);
return 0;
}
using the following Makefile,
OUTPUT = ./output
LIBBPF = ../libbpf
LIBBPF_SRC = $(abspath $(LIBBPF)/src)
LIBBPF_OBJ = $(abspath $(OUTPUT)/libbpf.a)
CC = gcc
CLANG = clang
ARCH := $(shell uname -m)
# ARCH := $(subst x86_64,amd64,$(ARCH))
GOARCH := $(ARCH)
BPFTOOL = $(shell which bpftool || /bin/false)
BTFFILE = /sys/kernel/btf/vmlinux
DBGVMLINUX = /usr/lib/debug/boot/vmlinux-$(shell uname -r)
GIT = $(shell which git || /bin/false)
VMLINUXH = vmlinux.h
# libbpf
LIBBPF_OBJDIR = $(abspath ./$(OUTPUT)/libbpf)
LIBBPF_DESTDIR = $(abspath ./$(OUTPUT))
CFLAGS = -ggdb -gdwarf -O2 -Wall -fpie -Wno-unused-variable -Wno-unused-function
LDFLAGS =
BPF_CFLAGS_STATIC = "-I$(abspath $(OUTPUT))"
BPF_LDFLAGS_STATIC = "-lelf -lz $(LIBBPF_OBJ)"
CGO_CFLAGS_STATIC = "-I$(abspath $(OUTPUT))"
CGO_LDFLAGS_STATIC = "-lelf -lz $(LIBBPF_OBJ)"
CGO_EXTLDFLAGS_STATIC = '-w -extldflags "-static"'
CGO_CFGLAGS_DYN = "-I. -I/usr/include/"
CGO_LDFLAGS_DYN = "-lelf -lz -lbpf"
CGO_EXTLDFLAGS_DYN = '-w'
## program
.PHONY: $(PROGRAM)
.PHONY: $(PROGRAM).bpf.c
PROGRAM = main
all:
$(MAKE) -C . $(PROGRAM)
# vmlinux header file
.PHONY: vmlinuxh
vmlinuxh: $(VMLINUXH)
$(VMLINUXH): $(OUTPUT)
ifeq ($(wildcard $(BPFTOOL)),)
#echo "ERROR: could not find bpftool"
#exit 1
endif
#if [ -f $(DBGVMLINUX) ]; then \
echo "INFO: found dbg kernel, generating $(VMLINUXH) from $(DBGVMLINUX)"; \
$(BPFTOOL) btf dump file $(DBGVMLINUX) format c > $(VMLINUXH); \
fi
#if [ ! -f $(BTFFILE) ] && [ ! -f $(DBGVMLINUX) ]; then \
echo "ERROR: kernel does not seem to support BTF"; \
exit 1; \
fi
#if [ ! -f $(VMLINUXH) ]; then \
echo "INFO: generating $(VMLINUXH) from $(BTFFILE)"; \
$(BPFTOOL) btf dump file $(BTFFILE) format c > $(VMLINUXH); \
fi
# static libbpf generation for the git submodule
.PHONY: libbpf
libbpf: $(LIBBPF_OBJ)
$(LIBBPF_OBJ): $(LIBBPF_SRC) $(wildcard $(LIBBPF_SRC)/*.[ch]) | $(OUTPUT)/libbpf
CC="$(CC)" CFLAGS="$(CFLAGS)" LD_FLAGS="$(LDFLAGS)" \
$(MAKE) -C $(LIBBPF_SRC) \
BUILD_STATIC_ONLY=1 \
OBJDIR=$(LIBBPF_OBJDIR) \
DESTDIR=$(LIBBPF_DESTDIR) \
INCLUDEDIR= LIBDIR= UAPIDIR= prefix= libdir= install
$(LIBBPF_SRC):
ifeq ($(wildcard $#), )
echo "INFO: updating submodule 'libbpf'"
$(GIT) submodule update --init --recursive
endif
# output dir
$(OUTPUT):
mkdir -p $(OUTPUT)
$(OUTPUT)/libbpf:
mkdir -p $(OUTPUT)/libbpf
## program bpf dependency
$(PROGRAM).bpf.o: $(PROGRAM).bpf.c | vmlinuxh
$(CLANG) $(CFLAGS) -target bpf -D__TARGET_ARCH_x86 -I. -I$(OUTPUT) -c $< -o $#
## GO example
.PHONY: $(PROGRAM)
$(PROGRAM): libbpf | $(PROGRAM).bpf.o
CC=$(CLANG) \
CGO_CFLAGS=$(CGO_CFLAGS_STATIC) \
CGO_LDFLAGS=$(CGO_LDFLAGS_STATIC) \
GOARCH=$(GOARCH) \
go build \
-tags netgo -ldflags $(CGO_EXTLDFLAGS_STATIC) \
-o $(PROGRAM) ./$(PROGRAM).go
## clean
clean:
$(MAKE) -C $(LIBBPF_SRC) clean
rm -rf $(OUTPUT)
rm -rf $(VMLINUXH)
rm -rf $(PROGRAM) $(PROGRAM)-*static $(PROGRAM)-*dynamic
rm -rf $(PROGRAM).bpf.o $(PROGRAM).o
I am getting the error,
error: no member named 'si' in 'struct pt_regs'
bpf_probe_read(file_name, sizeof(file_name), PT_REGS_PARM2(ctx));
^~~~~~~~~~~~~~~~~~
./output/bpf/bpf_tracing.h:273:46: note: expanded from macro 'PT_REGS_PARM2'
#define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG)
~~~~~~~~~~~~~~~~~ ^
./output/bpf/bpf_tracing.h:78:24: note: expanded from macro '__PT_PARM2_REG'
#define __PT_PARM2_REG si
^
I realized this is due to some problem with the definition of the MACRO PT_REGS_PARM2, which is defined as #define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG) in bpf_tracing.h header file, which does some sort of pointer casting to obtain the pt_regs pointer for x, and then access the member given by __PT_PARM2_REG which is a MACRO defined as si. So I guess the error is that there is no such register in my x86 architecture specific struct pt_regs, I am not sure why it uses that register for this macro. Is there any error in the specification of the architecture in Makefile, or is there is some error in the code in bpf_tracing.h? The architecture I am compiling for is x86_64.
So the solution was to replace PT_REGS_PARM2(ctx) by ctx->si directly, since the struct pt_regs is defined inside vmlinux.h itself, and using the macro PT_REGS_PARM2 defaults to using the struct definition inside bpf_tracing.h where the si member is not included for some reason. The struct pt_regs in vmlinux.h is defined as,
struct pt_regs {
long unsigned int r15;
long unsigned int r14;
long unsigned int r13;
long unsigned int r12;
long unsigned int bp;
long unsigned int bx;
long unsigned int r11;
long unsigned int r10;
long unsigned int r9;
long unsigned int r8;
long unsigned int ax;
long unsigned int cx;
long unsigned int dx;
long unsigned int si;
long unsigned int di;
long unsigned int orig_ax;
long unsigned int ip;
long unsigned int cs;
long unsigned int flags;
long unsigned int sp;
long unsigned int ss;
};
So I used pointer casting to get the character pointer to ctx->si, and then read the contents onto file_name as before. The updated ebpf file,
#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>
#include <string.h>
SEC("kprobe/do_sys_openat2")
int kprobe__do_sys_openat2(struct pt_regs *ctx)
{
char file_name[256];
char *file_name_ptr = (char *)ctx->si;
if (!file_name_ptr)
{
// handle error: invalid memory address
return 0;
}
bpf_probe_read(file_name, sizeof(file_name), file_name_ptr);
char fmt[] = "open file %s\n.";
bpf_trace_printk(fmt, sizeof(fmt), &file_name);
return 0;
}
char _license[] SEC("license") = "GPL";
This works!
Related
I defined the next two static functions in a file named Grafico.h.
static inline interface_t * obtener_intf_por_nombre(nodo_t *nodo, char *nombre_if) {
for (int i = 0; i < MAX_INTF_POR_NODO; ++i)
{
if(!nodo->intf[i]) return NULL;
if(strncmp(nodo->intf[i]->nombre_if, nombre_if, TAM_NOMBRE_IF) == 0) {
return nodo->intf[i];
}
}
return NULL;
}
static inline nodo_t * obtener_nodo_por_nombre(grafico_t *topologia, char *nombre_nodo) {
return obtener_elemento(topologia->lista_nodos, nombre_nodo);
}
In my main file I called these functions without remembering they were static, and I didn't get any warning or error from the compiler related to it.
#include <stdio.h>
#include "Net.h"
#include "Grafico.h"
#include "Topologias.h"
#include "CommandParser/libcli.h"
#include "clired.c"
extern grafico_t *const_primera_topo();
grafico_t *topo = NULL;
int main(void) {
inic_cli_red();
topo = const_primera_topo();
sleep(2);
nodo_t *nodo_trans = obtener_nodo_por_nombre(topo, "R0");
interface_t *interface_trans = obtener_intf_por_nombre(nodo_trans, "ethR0/0");
char *mensaje = "Este es un mensaje de prueba\0";
printf("Llegamos hasta aquí señores. Fue un honor.\n");
enviar_paquete(mensaje, strlen(mensaje), interface_trans);
start_shell();
return 0;
}
In case it's useful, here is my makefile.
TARGET = $(BIN_DIR)/sim_tcp_ip
LIBS = -lpthread -L ./CommandParser -lcli -lrt
OBJS = $(OBJ_DIR)/prueba.o \
$(OBJ_DIR)/ListaEnlazadaGenerica.o \
$(OBJ_DIR)/Grafico.o \
$(OBJ_DIR)/Net.o \
$(OBJ_DIR)/Topologias.o \
$(OBJ_DIR)/Com.o \
$(OBJ_DIR)/Utiles.o \
$(OBJ_DIR)/Capa2.o
BIN_DIR = ./bin
OBJ_DIR = ./obj
INC_DIR = ./inc
SRC_DIR = ./src
CFLAGS = -g -lpthread -Wall -I$(INC_DIR)
$(TARGET): $(OBJS) CommandParser/libcli.a
mkdir -p $(BIN_DIR)
gcc $(CFLAGS) $(OBJS) -o $(TARGET) $(LIBS)
$(OBJ_DIR)/%.o : %.c
mkdir -p $(OBJ_DIR)
gcc -c -MD $(CFLAGS) $< -o $#
CommandParser/libcli.a:
(cd CommandParser; make)
-include $(OBJ_DIR)/*.d
.PHONY: clean
clean:
rm -rf $(OBJ_DIR) $(BIN_DIR)
(cd CommandParser; make clean)
all:
make
Is there something wrong with the definition of these static functions?
When you #include a file, it is equivalent to copypasting the contents of that file in place of that line. So the static functions are in the same compilation unit, and hence just as usable as any other static thing you define in the .c file itself.
The problem is that you have declared them in your header file, Graphico.h!
The static keyword just means that if you compile a source C file prog.c into an object file prog.o, then any static functions in prog.c will be hard coded as memory addresses in prog.o. That is to say, whereas a normal function has an entry defined in the symbol table of prog.o, that is used when prog.o is linked with another object file, a static function does not.
I am trying to compile an old C program on Centos8 Linux and it is failing, i'd appreciate any help.
I have broken below into the Makefile used, the error and code.
Any help would be much appreciated.
Thank you.
Makefile:
CC = gcc
C_FLAGS = -Wall -O0 -ggdb -march=i686 -m32 -DDEBUG=1
C_FLAGS2 = -Wall -O4 -march=i686 -s
LIBS = -lcrypt -lmysqlclient
Error
gcc -c -Wall -O0 -ggdb -march=i686 -m32 -DDEBUG=1 chat.c
In file included from chat.c:12:
command.h:152:30: error: array type has incomplete element type ‘struct cmd_type’
extern const struct cmd_type cmd_table[];
^~~~~~~~~
command.h
#ifndef _COMMAND_H
#define _COMMAND_H
/* returns 0 if not a command, or if the command is handled "on the fly".
otherwise, it handles it and returns 1 */
int execute_command(request_rec *r);
/* does that "print everything you've got" thing */
void archive_command(request_rec *r, user_rec **user_list,
message_rec **message_list, char *title, char *topic,
int chat_open);
#define DECLARE_CHAT_CMD( cmd ) CHAT_CMD cmd
typedef int CHAT_CMD (request_rec *r, char *message_text);
extern const struct cmd_type cmd_table[];
struct cmd_type
{
char *name;
CHAT_CMD *cmd;
int rank;
int room;
};
DECLARE_CHAT_CMD(do_admin);
DECLARE_CHAT_CMD(do_alink);
DECLARE_CHAT_CMD(do_archive);
DECLARE_CHAT_CMD(do_background);
DECLARE_CHAT_CMD(do_bgcolor);
DECLARE_CHAT_CMD(do_boot);
DECLARE_CHAT_CMD(do_bottom);
DECLARE_CHAT_CMD(do_box);
DECLARE_CHAT_CMD(do_bozo);
DECLARE_CHAT_CMD(do_close);
DECLARE_CHAT_CMD(do_color);
DECLARE_CHAT_CMD(do_commands);
#endif /* _COMMAND_H */
I am in the process of converting my gmake build to cmake builds. The application builds fine with gmake, but I get the errors below when I use cmake.
Below are the gmake and cmake files.
parent Makefile
CC := gcc
CFLAGS := -g -w -m32
INC_DIR := ../includes
OBJ_DIR := ../objects
BIN_DIR := ../bin
child Makefile
include ../../Makefile
SHR_FX := ../$(OBJ_DIR)/shrfx.o
SHRXML := ../$(OBJ_DIR)/shrxml.o
TMP_BIN_DIR = ../$(BIN_DIR)
TMP_INC_DIR = ../$(INC_DIR)
EXECUTABLES := common flogmon
all: $(EXECUTABLES)
%: %.c OAhelper.c OAhelper.h $(SHR_FX) $(TMP_INC_DIR)
#-rm -f $# ## QUIET (#). CONTINUE IF FILE NOT FOUND (-)
$(CC) $(CFLAGS) -I $(TMP_INC_DIR) $(LDLIBPATHFLAGS) -o $# $#.c OAhelper.c $(SHR_FX)
#-chmod 0775 $# #SH(#),CONT(-). Allow others to do it.
mv $# $(TMP_BIN_DIR)
parent CMakeList.txt
cmake_minimum_required(VERSION 2.8.9)
project(program)
set(CMAKE_BUILD_TYPE Release)
set (EXECUTABLE_OUTPUT_PATH "/home/user/workspace/program")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -w -m32")
add_subdirectory(opaid/opaid_helper)
child CMakeList.txt
cmake_minimum_required(VERSION 2.8.9)
#Bring the headers
include_directories(../../includes)
set (PROJ_LIST "common;flogmon")
message ( STATUS "CFLAGS : " ${CMAKE_C_FLAGS})
foreach (PROJ ${PROJ_LIST})
project(${PROJ})
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath=${EXECUTABLE_OUTPUT_PATH}:${EXECUTABLE_OUTPUT_PATH}../RSA/cryptocme3001/library/lib")
add_executable(${PROJ} ${PROJ}.c OAhelper.c )
target_link_libraries(${PROJ} LINK_PUBLIC shrfx)
install(TARGETS ${PROJ} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
endforeach()
Error
Building C object /CMakeFiles/common.dir/common.c.o
In file included from /usr/include/features.h:375:0,
from /usr/include/sys/poll.h:22,
from /usr/include/poll.h:1,
from /home/user/workspace/program/src/common.c:26:
/usr/include/sys/stat.h:503:1: error: conflicting types for ‘stat64’
__NTH (stat64 (const char *__path, struct stat64 *__statbuf))
^
In file included from
/home/user/workspace/program/src/../../includes/fxgen.h:205:0,
from /home/user/workspace/program/src/../../includes/fx.h:286,
from /home/user/workspace/program/src/common.c:39:
/usr/include/sys/stat.h:229:12: note: previous declaration of ‘stat64’
was here extern int stat64 (const char *__restrict __file,
If I look in /usr/include/sys/stat.h...
503
# if defined __USE_LARGEFILE64 \
&& (! defined __USE_FILE_OFFSET64 \
|| (defined __REDIRECT_NTH && defined __OPTIMIZE__))
__extern_inline int
__NTH (stat64 (const char *__path, struct stat64 *__statbuf))
{
return __xstat64 (_STAT_VER, __path, __statbuf);
}
229
#ifdef __USE_LARGEFILE64
extern int stat64 (const char *__restrict __file,
struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2));
extern int fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2));
#endif
Adding this to my CMAKEList.txt solved the problem:
STRING(REPLACE "-O3" "-O0" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
I'm trying to build simple dll which uses library UMFPACK.
Here is my file "umfsolver.c":
#include <stdio.h>
#include <stdlib.h>
#include "umfpack.h"
#include "amd.h"
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
typedef struct problem_struct
{
double Control [UMFPACK_CONTROL];
double Info [UMFPACK_INFO];
int *Ti;
int *Tj;
double *Tx;
int nrow;
int ncol;
int nz;
} problem;
EXPORT problem* __stdcall create(int nrows, int ncols, int nnonzero)
{
problem *prob;
prob = (problem*) malloc(sizeof (problem)) ;
if (!prob) return (NULL);
prob->nrow = nrows;
prob->ncol = ncols;
prob->nz = nnonzero;
printf("Creating...\n");
umfpack_di_defaults (prob->Control) ;
prob->Control [UMFPACK_PRL] = 3 ;
prob->Control [UMFPACK_BLOCK_SIZE] = 32 ;
prob->Ti = (int *) malloc (nnonzero * sizeof (int)) ;
prob->Tj = (int *) malloc (nnonzero * sizeof (int)) ;
prob->Tx = (double *) malloc (nnonzero * sizeof (double)) ;
if (!prob->Ti || !prob->Tj || !prob->Tx ) return (NULL);
return prob;
}
And here is my makefile:
all: libs umfsolver
include ../../SuiteSparse_config/SuiteSparse_config.mk
#-------------------------------------------------------------------------------
# the optional Partition module requires METIS, CAMD, and CCOLAMD
I_WITH_PARTITION =
LIB_WITH_PARTITION =
CONFIG1 = -DNCHOLMOD
CONFIG2 = -DNPARTITION
ifeq (,$(findstring -DNCHOLMOD, $(UMFPACK_CONFIG)))
# CHOLMOD is requested. See if it is available
ifeq (../../CHOLMOD, $(wildcard ../../CHOLMOD))
ifeq (../../COLAMD, $(wildcard ../../COLAMD))
# CHOLMOD and COLAMD are available
CONFIG1 =
LIB_WITH_CHOLMOD = ../../CHOLMOD/Lib/libcholmod.a \
../../COLAMD/Lib/libcolamd.a
# check if METIS is requested and available
ifeq (,$(findstring -DNPARTITION, $(CHOLMOD_CONFIG)))
# METIS is requested. See if it is available
ifeq ($(METIS_PATH), $(wildcard $(METIS_PATH)))
ifeq (../../CAMD, $(wildcard ../../CAMD))
ifeq (../../CCOLAMD, $(wildcard ../../CCOLAMD))
# METIS, CAMD, and CCOLAMD are available
LIB_WITH_PARTITION = $(METIS) \
../../CCOLAMD/Lib/libccolamd.a \
../../CAMD/Lib/libcamd.a
I_WITH_PARTITION = -I$(METIS_PATH)/Lib \
-I../../CCOLAMD/Include -I../../CAMD/Include
CONFIG2 =
endif
endif
endif
endif
endif
endif
endif
#-------------------------------------------------------------------------------
C = $(CC) $(CF) $(UMFPACK_CONFIG) $(CONFIG1) $(CONFIG2) \
-I../Include -I../../AMD/Include -I../../SuiteSparse_config
INC = ../Include/umfpack.h ../../AMD/Include/amd.h ../../SuiteSparse_config/SuiteSparse_config.h
LIBS = $(LAPACK) $(BLAS) $(XERBLA) $(LIB) $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) $(CUBLAS_LIB) $(CUDART_LIB)
../Lib/libumfpack.a:
( cd ../Lib ; $(MAKE) )
../../AMD/Lib/libamd.a:
( cd ../../AMD ; $(MAKE) library )
../../SuiteSparse_config/libsuitesparseconfig.a:
( cd ../../SuiteSparse_config ; $(MAKE) library )
../../CHOLMOD/Lib/libcholmod.a:
- ( cd ../../CHOLMOD && $(MAKE) library )
../../COLAMD/Lib/libcolamd.a:
- ( cd ../../COLAMD && $(MAKE) library )
../../CCOLAMD/Lib/libccolamd.a:
- ( cd ../../CCOLAMD && $(MAKE) library )
../../CAMD/Lib/libcamd.a:
- ( cd ../../CAMD && $(MAKE) library )
$(METIS):
( cd $(METIS_PATH) && $(MAKE) )
UMFPACK = ../Lib/libumfpack.a ../../AMD/Lib/libamd.a \
../../SuiteSparse_config/libsuitesparseconfig.a \
$(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION)
libs: $(UMFPACK)
umfsolver: umfsolver.c $(UMFPACK)
$(C) -c -DBUILD_DLL umfsolver.c
$(C) -shared -o umfsolver.dll umfsolver.o -Wl,--add-stdcall-alias $(UMFPACK) $(LIBS) -lm
I used variables:
CF = -O3 -fexceptions -fPIC
CC = cc
LIB = -lm -lrt
UMFPACK_CONFIG = -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt
MAKE = make
CUBLAS_LIB =
CUDART_LIB =
XERBLA =
BLAS =
LAPACK =
METIS_PATH = ../../metis-4.0
METIS = ../../metis-4.0/libmetis.a
It builds with no errors. When I'm calling function create from another program (using static dllimport), it works until some library function need to be called inside create.
It seems like the program goes to infinite loop when either it calls printf("Creating...\n") or umfpack_di_defaults (prob->Control).
When I type make, I get this:
cc -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt -I../Include -I../../AMD/Include -I../../SuiteSparse_config -c -DBUILD_DLL umfsolver.c
cc1: warning: fPIC ignored for target (all code is position independent)
cc -O3 -fexceptions -fPIC -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt -I../Include -I../../AMD/Include -I../../SuiteSparse_config -shared -o umfsolver.dll umfsolver.o ../Lib/libumfpack.a ../../AMD/Lib/libamd.a ../../SuiteSparse_config/libsuitesparseconfig.a ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a -lm -lrt ../../CHOLMOD/Lib/libcholmod.a ../../COLAMD/Lib/libcolamd.a ../../metis-4.0/libmetis.a ../../CCOLAMD/Lib/libccolamd.a ../../CAMD/Lib/libcamd.a -Wl,--add-stdcall-alias
I guess that I should somehow change the makefile to put all library files together?
How can I do this? Can anyone explain me this?
Thanks!
A Header file(stdint.h) is not included. I know a lot of code is following, but I have really no idea.
My Files:
gdt.c
/* We need 8 segments */
#include <stdint.h>
#include "gdt.h"
#define GDT_SIZE 8
uint32_t intr;
gdt_entry gdtable[GDT_SIZE];
include/gdt.h
#ifndef GDT_H
#define GDT_H
#include <stdint.h>
struct gdt_entry{
uint_16t limit;
uint_32t base :24;
uint_32t accessbyte :8;
uint_32t limit2 :4;
uint_32t flags2 :4;
uint_32t base2 :8;
}__attribute__((packed));
#endif
include/stdint.h
#ifndef STDINT_H
#define STDINT_H
typedef unsigned long long uint64_t;
typedef unsigned int uint32_t;
typedef unsigned short uint16_t;
typedef unsigned char uint8_t;
typedef signed long long int64_t;
typedef signed int int32_t;
typedef signed short int16_t;
typedef signed char int8_t;
#endif
Makefile:
SRCS = $(shell find -name '*.[cS]')
OBJS = $(addsuffix .o,$(basename $(SRCS)))
CC = gcc
LD = ld
ASFLAGS = -m32
CFLAGS = -m32 -Wall -g -fno-stack-protector -I include
LDFLAGS = -melf_i386 -Tkernel.ld
kernel: $(OBJS)
$(LD) $(LDFLAGS) -o $# $^
%.o: %.c
$(CC) $(CFLAGS) -c -o $# $^
%.o: %.S
$(CC) $(ASFLAGS) -c -o $# $^
clean:
rm $(OBJS)
.PHONY: clean
kernel.ld
/* start should be executed first */
ENTRY(_start)
/*
* thats how the sections should be written in the .elf binary
*/
SECTIONS
{
/*
* the first section has a 1MB Offset for the grub bootloader
*/
. = 0x100000;
/*
* the multiboot header comes first
*/
.text : {
*(multiboot)
*(.text)
}
.data ALIGN(4096) : {
*(.data)
}
.rodata ALIGN(4096) : {
*(.rodata)
}
.bss ALIGN(4096) : {
*(.bss)
}
}
gcc output:
gcc -m32 -c -o start.o start.S
gcc -m32 -Wall -g -fno-stack-protector -I include -c -o gdt.o gdt.c
In file included from gdt.c:3:0:
include/gdt.h:5:2: error: unknown type name ‘uint_16t’
include/gdt.h:6:2: error: unknown type name ‘uint_32t’
include/gdt.h:7:2: error: unknown type name ‘uint_32t’
include/gdt.h:8:2: error: unknown type name ‘uint_32t’
include/gdt.h:9:2: error: unknown type name ‘uint_32t’
include/gdt.h:10:2: error: unknown type name ‘uint_32t’
gdt.c:7:1: error: unknown type name ‘gdt_entry’
make: *** [gdt.o] Error 1
I think you should use uint32_t instead of the non-standard uint_32t. It's at least the third variant I've come across, previously I've also seen u_int32_t.
There was another issue:
gdt_entry gdtable[GDT_SIZE]; should be struct gdt_entry gdtable[GDT_SIZE]