compiling my own kernel (not from linux-kernel source) - c

I'm following the kernel tutorial from here
im having problems compiling my files.
i get the following errors when i try to compile:
main.c:8: error: expected declaration specifiers or ‘...’ before ‘size_t’
main.c:8: error: conflicting types for ‘memcpy’
./include/system.h:5: note: previous declaration of ‘memcpy’ was here
main.c: In function ‘memcpy’:
main.c:12: error: ‘count’ undeclared (first use in this function)
main.c:12: error: (Each undeclared identifier is reported only once
main.c:12: error: for each function it appears in.)
main.c: At top level:
main.c:16: error: expected declaration specifiers or ‘...’ before ‘size_t’
main.c:16: error: conflicting types for ‘memset’
./include/system.h:6: note: previous declaration of ‘memset’ was here
main.c: In function ‘memset’:
main.c:19: error: ‘count’ undeclared (first use in this function)
main.c: At top level:
main.c:23: error: expected declaration specifiers or ‘...’ before ‘size_t’
main.c:23: error: conflicting types for ‘memsetw’
./include/system.h:7: note: previous declaration of ‘memsetw’ was here
main.c: In function ‘memsetw’:
main.c:26: error: ‘count’ undeclared (first use in this function)
main.c: At top level:
main.c:30: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘strlen’
main.c:49: warning: return type of ‘main’ is not ‘int’
main.c: In function ‘main’:
main.c:64: warning: pointer targets in passing argument 1 of ‘puts’ differ in signedness
./include/system.h:13: note: expected ‘unsigned char *’ but argument is of type ‘char *’
main.c:51: warning: unused variable ‘i’
scrn.c: In function ‘scroll’:
scrn.c:24: warning: passing argument 1 of ‘memcpy’ from incompatible pointer type
./include/system.h:5: note: expected ‘unsigned char *’ but argument is of type ‘short unsigned int *’
scrn.c:24: warning: passing argument 2 of ‘memcpy’ from incompatible pointer type
./include/system.h:5: note: expected ‘const unsigned char *’ but argument is of type ‘short unsigned int *’
scrn.c: In function ‘puts’:
scrn.c:139: warning: pointer targets in passing argument 1 of ‘strlen’ differ in signedness
./include/system.h:8: note: expected ‘const char *’ but argument is of type ‘unsigned char *’
My files are exact copies of the ones from the tutorial.
I can see that in main.c the functions are defined like so
void *memcpy(void *dest,const void *src, size_t count)
but in my system.h file they are defined like so
extern unsigned char *memcpy(unsigned char *dest,const unsigned char *src, int count)
C is not my primary language but i am in the process of learning it so I apologize if my question is simple but I would think that these definitions should be the same not?

Probably your issue is that size_t isn't the same as int on your platform, or size_t isn't specified correctly at all. The pointer types should be OK (technically, they should match too, but on most systems sizeof(char*) == sizeof(void*)).
If you're developing your own kernel, you'd want to write your own system.h. If you're writing both system.h and main.c, you can make them match up however you'd like. If you look at this page of the tutorial, you'd see that header and C source both declare memcpy as:
unsigned char *memcpy(unsigned char *dest, const unsigned char *src, int count);
But if you download the example source files at the end of the tutorial, you find it is instead:
void *memcpy(void *dest, const void *src, size_t count);
Looking at the top of that file, you find the following comment:
/* bkerndev - Bran's Kernel Development Tutorial
* By: Brandon F. (friesenb#gmail.com)
* Desc: Main.c: C code entry.
*
* Notes: No warranty expressed or implied. Use at own risk. */
It doesn't look like you're trying to follow a tutorial, but rather that you're trying to cut and paste code from a tutorial. That's like trying to learn to perform brain surgery by following along in a book. You might get it to work, but if you don't really understand what you're doing... well, please do the world a favor and don't use it for anything critical.

Replace size_t by int in each method definition on main.c

Related

flex bison windows introduction

As I'm new to lexer and parser, so I'm trying to read and understand others code.
Here is the code i'm trying to use : https://gist.github.com/justjkk/436828
But it's giving me error. How can I resolve this?
E:\flex_bison_test>gcc lex.yy.c y.tab.c -o json.exe
json.l: In function 'yylex':
json.l:34:11: warning: assignment to 'YYSTYPE' {aka 'int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]
yylval=strclone(yytext);
^
json.l:38:11: warning: assignment to 'YYSTYPE' {aka 'int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]
yylval=strclone(yytext);
^
json.l: In function 'strclone':
json.l:82:15: warning: implicit declaration of function 'strlen' [-Wimplicit-function-declaration]
int len = strlen(str);
^~~~~~
json.l:82:15: warning: incompatible implicit declaration of built-in function 'strlen'
json.l:82:15: note: include '<string.h>' or provide a declaration of 'strlen'
json.l:79:1:
+#include <string.h>
%%
json.l:82:15:
int len = strlen(str);
^~~~~~
json.l:84:5: warning: implicit declaration of function 'strcpy' [-Wimplicit-function-declaration]
strcpy(clone,str);
^~~~~~
json.l:84:5: warning: incompatible implicit declaration of built-in function 'strcpy'
json.l:84:5: note: include '<string.h>' or provide a declaration of 'strcpy'
y.tab.c: In function 'yyparse':
y.tab.c:627:16: warning: implicit declaration of function 'yylex' [-Wimplicit-function-declaration]
# define YYLEX yylex ()
^~~~~
y.tab.c:1272:16: note: in expansion of macro 'YYLEX'
yychar = YYLEX;
^~~~~
y.tab.c:1540:7: warning: implicit declaration of function 'yyerror'; did you mean 'yyerrok'? [-Wimplicit-function-declaration]
yyerror (YY_("syntax error"));
^~~~~~~
yyerrok
json.y: At top level:
json.y:80:6: warning: conflicting types for 'yyerror'
void yyerror (char const *s) {
^~~~~~~
y.tab.c:1540:7: note: previous implicit declaration of 'yyerror' was here
yyerror (YY_("syntax error"));
^~~~~~~
E:\flex_bison_test>
Or these should remain as it is.
All the commands, I have given :
flex json.l
bison -dy json.y
gcc lex.yy.c y.tab.c -o json.exe
Simply:
#include <string.h>
in your flex definitions section on top of json.l should fix it for you.
There's also a Makefile in the repository you pointed to. Maybe you should use that. You don't seem to be generating the parser files properly. See comment below.
As for the remaining warnings:
warning: implicit declaration of function 'yyerror';
warning: implicit declaration of function 'yylex';
These can be easily fixed by adding declarations of yylex() and yyerror should be present in the bison prologue section at the top of your json.y:
%{
int yylex();
void yyerror(const char *s);
%}
As for these ones:
json.l:34:11: warning: assignment to 'YYSTYPE' {aka 'int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]
yylval=strclone(yytext);
^
json.l:38:11: warning: assignment to 'YYSTYPE' {aka 'int'} from 'char *' makes integer from pointer without a cast [-Wint-conversion]
yylval=strclone(yytext);
^
They're a bit more subtle. I would suggest have a look here on how to use yylval for correctly passing on strings from the lex's tokens into the parser's actions. The problem now is that yylval is a bare int but it ends up being assigned char pointers for both NUMBER and STRING tokens.

How is the linking done for string functions in C?

I tried to using two different functions from sting.h header file (without including it) strlen() and strtok(). Strlen executed successfully without any error (but some warnings), strtok failed at runtime. Why is it that strlen() function worknig gine but not strtok() if I don't include the header file? I suppose there is something in the linking process that I don't understand. Please clarify for such behavior. However, the program terminates successfully if I print a as '%c' instead of '%s' (strtok returns a garbage value).
CODE:
int main()
{
char string[] = "This is a String";
printf("\nLength of sting is %d\n",strlen(string));
}
WARNINGS:
hello.c: In function ‘main’:
hello.c:4:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
hello.c:4:37: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
hello.c:4:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]
OUTPUT:
$ ./a.out
Length of sting is 16
CODE:
int main()
{
char string[] = "This is a String";
printf("\nLength of sting is %d\n",strlen(string));
char *a = strtok(string," ");
printf("%s",a);
}
WARNINGS:
$ gcc hello.c
hello.c: In function ‘main’:
hello.c:4:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
hello.c:4:37: warning: incompatible implicit declaration of built-in function ‘strlen’ [enabled by default]
hello.c:4:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat]
hello.c:5:12: warning: initialization makes pointer from integer without a cast [enabled by default]
OUTPUT:
$ ./a.out
Length of sting is 16
Segmentation fault (core dumped)
The linking is done implicitly for most of the C standard library. You just have to include the headers of what you use (that's the warnings).
When you don't, your compiler (which is compiling your code as ANSI C) assumes the functions return int, instead of their documented return types. Your program has undefined behavior because of that. Always heed warnings!
You must include the headers string.h and stdio.h.
The first program works because you were lucky enough in that strlen is supposed to return an integer (a size_t to be exact, but it appears on your system the value representation for integers and size_t lets the program slide through).
The second fails because strtok returns a char* but it's assumed an int due to your missing include directives. int and char* are not compatible types, so the "pointer" you get isn't valid.
Sting is a singer, not a C header... Still, the problem is that in C, when you use functions that were not declared, the compiler guesses them to have the types of the arguments you first pass to them and returning an int.
That's the reason why you get all these warnings: several undeclared functions you use don't actually have the deduced signature (although they are not too wrong, and end up working), and the real strtok returns a pointer, not an int (the warning in facts says that you are assigning an int to a pointer without a cast). The crash you are getting most probably comes from the fact that the original pointer is 64 bit, but is truncated to 32 bit when is erroneously considered an int before being assigned to a.
Still, the point to take home is: include headers and don't ever rely on implicit function declaration. It's a dangerous mess that exists only for backward compatibility reasons.

Is long string literal's type long int*?

According to the answers in this question, a literal like L"test" has type wchar_t[5]. But the following code with GCC seems to say something different:
int main()
{
struct Test{char x;} s;
s="Test"; // ok, char* as expected
s=L"Test"; // ??? I'd expect wchar_t*
return 0;
}
Here's how I compile it (gcc 5.2, but same results are with 4.5 and 4.8):
$ gcc test.c -o test -std=c99
test.c: In function ‘main’:
test.c:4:6: error: incompatible types when assigning to type ‘struct Test’ from type ‘char *’
s="Test"; // ok, char* as expected
^
test.c:5:6: error: incompatible types when assigning to type ‘struct Test’ from type ‘long int *’
s=L"Test"; // ??? I'd expect wchar_t*
^
Apparently, instead of the expected array of wchar_t I get array of long int. What's wrong here?
The type wchar_t is not a fundamental type, like char. It is an implementation-defined synonym of an integer type1.
1 (Quoted from: ISO/IEC 9899:201x 7.19 Common definitions 2.)
wchar_t which is an integer type whose range of values can represent distinct codes for all
members of the largest extended character set specified among the supported locales;

Expect 'struct netif *' but argument is of type 'struct netif *' [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I get the following error with gcc when I declare a struct netif * from a function scope (where the compile doesn't complain) to global scope:
src/main.c:114:3: warning: passing argument 1 of 'low_level_init' from incompatible pointer type [enabled by default]
src/main.c:62:13: note: expected 'struct netif *' but argument is of type 'struct netif *'
Why is does compiler give the following "non-sensical" complaint?
expected 'stuct netif *' but argument is of type 'struct netif *'
This "full program"
void foonetif(struct netif *dst) {
if (dst) return;
return;
}
struct netif {
double bar;
};
int main(void) {
struct netif *netif = 0; /* NULL */
foonetif(netif);
return 0;
}
generates this output from gcc 10398683.c (gcc version 4.6.3), so with all default options
10398683.c:1:22: warning: ‘struct netif’ declared inside parameter list [enabled by default]
10398683.c:1:22: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
10398683.c: In function ‘main’:
10398683.c:12:3: warning: passing argument 1 of ‘newnetif’ from incompatible pointer type [enabled by default]
10398683.c:1:6: note: expected ‘struct netif *’ but argument is of type ‘struct netif *’
Note the last warning (really a note) :)
The problem is scope. The first struct netif is in the scope of the function's argument list, and goes out of scope after that function ends. The second struct netif is defined in a new scope. These are thereby different structure types with different tags which happen to have the same name. Just like int i; and int i; in two different functions are different variables that happen to have the same name.
An interesting question; have fallen foul of this myself; mostly due to horrid hacks involving dubious type casts on innocent memory-blocks.
This answer is really just a corollary to R's answer, which pretty much nails the issue (though i'm not quite sure about the and goes out of scope after that function ends.. bit)
For me, the key to this is perusal of:
(1) ISO C99 6.7.2:
Two types have compatible type if their types are the same. Additional
rules for determining whether two types are compatible are described
in 6.7.2 for type specifiers, in 6.7.3 for type qualifiers, and in
6.7.5 for declarators.46) Moreover, two structure, union, or enumerated types declared in separate translation units are compatible
if their tags and members satisfy the following requirements: If one
is declared with a tag, the other shall be declared with the same tag. ...
(2) C namespaces
Anyway, here's some code (~a couple of translation units) that hopefully demonstrates some possibly surprising behaviour for those that haven't yet hit this issue before:
blah.c:
#include <stdio.h>
struct bar {int a; int b;} stbar;
struct bar_ {int a; int d;} stbar_;
void foo(struct bar* pst);
void foo_(struct bar st);
void callfoo()
{
/*no warnings; possibly surprising results ! */
stbar.a=313;
stbar.b=31313;
foo(&stbar);
printf("called foo() with stbar: %d, %d\n", stbar.a, stbar.b);
/*generates incompatible types warnings:
blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’ */
stbar_.a=313;
stbar_.d=31313;
foo(&stbar_);
printf("called foo() with stbar_: %d, %d\n", stbar_.a, stbar_.d);
/*generates incompatible types warnings:
blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’ */
struct bar {float s; float t;} stbar;
foo(&stbar);
printf("called foo() with locally defined stbar: %f, %f\n", stbar.s, stbar.t);
}
void callfoo_()
{
stbar.a=313;
stbar.b=31313;
//passing in incompatible type by value ~ no warnings; possibly surprising results !
foo_(stbar);
/*uncomenting next line generates compiler error:
blah.c:47:5: error: incompatible type for argument 1 of ‘foo_’
blah.c:7:6: note: expected ‘struct bar’ but argument is of type ‘struct bar_’ */
//foo_(stbar_);
}
void main()
{
callfoo();
callfoo_();
}
blah_.c:
#include <stdio.h>
struct bar {int x; float z;} stbar;
void foo(struct bar* pst)
{
printf("foo : %d, %f\n", pst->x, pst->z);
pst->x=13;
pst->z=13.13;
}
void foo_(struct bar st)
{
printf("foo_ : %d, %f\n", st.x, st.z);
st.x=13;
st.z=13.13;
}
output:
$ gcc blah.c blah_.c
blah.c: In function ‘callfoo’:
blah.c:23:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar_ *’
blah.c:31:5: warning: passing argument 1 of ‘foo’ from incompatible pointer type [enabled by default]
blah.c:6:6: note: expected ‘struct bar *’ but argument is of type ‘struct bar *’
$ ./a.out
foo : 313, 0.000000
called foo() with stbar: 13, 1095898235
foo : 313, 0.000000
called foo() with stbar_: 13, 1095898235
foo : 13274075, 0.000000
called foo() with locally defined stbar: 0.000000, 13.130000
foo_ : 313, 0.000000
$ gcc --version
gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1 ...
Corollary of corollary: praise the gods for C++ namespaces.
Your "full program" wont compile.
struct netif is not declared before foonetif which uses it. Try moving the struct definition before its first use.

Weird Compiler Error in Parser Code

Parser.h
enum { PLUS, MINUS, DIVIDE, MULTIPLY, NUMBER, END } type;
int token;
/* parsing functions */
void parse_token (void);
Parser.c
void get_token (void)
{
token++;
parse_token(); /* LINE 11 */
}
void parse_token (void) /* LINE 14 */
{
if ( strchr ("1234567890.", token) )
type = NUMBER;
else if ( strchr ("+", token) )
type = PLUS;
else if ( strchr ("-", token) )
type = MINUS;
else if ( strchr ("/", token) )
type = DIVIDE;
else if ( strchr ("*",token) )
type = MULTIPLY;
else if ( token == '\0' )
type = END;
else
show_error(strcat("Couldn't parse token : ", token));
}
The Errors
parser.c:14:6: warning: conflicting types for ‘parse_token’ [enabled by default]
parser.c:11:2: note: previous implicit declaration of ‘parse_token’ was here
parser.c: In function ‘parse_token’:
parser.c:16:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:17:3: error: ‘type’ undeclared (first use in this function)
parser.c:17:3: note: each undeclared identifier is reported only once for each function it appears in
parser.c:17:10: error: ‘NUMBER’ undeclared (first use in this function)
parser.c:19:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:20:10: error: ‘PLUS’ undeclared (first use in this function)
parser.c:22:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:23:10: error: ‘MINUS’ undeclared (first use in this function)
parser.c:25:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:26:10: error: ‘DIVIDE’ undeclared (first use in this function)
parser.c:28:2: warning: passing argument 2 of ‘strchr’ makes integer from pointer without a cast [enabled by default]
/usr/include/string.h:235:14: note: expected ‘int’ but argument is of type ‘char *’
parser.c:29:10: error: ‘MULTIPLY’ undeclared (first use in this function)
parser.c:32:10: error: ‘END’ undeclared (first use in this function)
parser.c: In function ‘show_error’:
parser.c:40:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
I'm utterly bamboozled. :(.
Any help?
One you get it to compile (by including the header, as Luchian Grigore said), you'll find that you can't do strcat() on a constant string.
The constant string is allocated in read-only memory, and can't be modified. And even if you could modify it, you would be overwriting other things in memory.
You're not including your header, so there's no way for the translation unit to know about the declarations of type and token.
You need:
#include "Parser.h"
at the beginning of the implementation file.

Resources