Page 3 of 4

Re: Why is ld complaining?

Posted: Fri Nov 18, 2016 9:33 am
by matt11235
NunoLava1998 wrote:Meh, time to read a C book.
Hurrah! Proud of you.

Re: Why is ld complaining?

Posted: Fri Nov 18, 2016 10:19 am
by osdever
Lukand wrote:**Sigh**

Let me teach you a lesson (Pow!) about declaring, defining and usage of header files.

Header files are source code files which are used to make any function, variable, enum, #define, etc be public.
Declaring a function is thing that is required in header files, and required in some cases in normal source files.

Example:

Main.cpp

Code: Select all

#include"myheader.h"
#include<cstdio>
int main()
{
    printf("%d", add(2,3));
    return 0;
}
Basicarithmetic.cpp

Code: Select all

#include"myheader.h"
int add(int a, int b)
{
    return a+b;
}
myheader.h

Code: Select all

#pragma once
int add(int a, int b);
OR

Code: Select all

#pragma once
int add(int, int);
I hope we learned something today.

I think that teaching him is just a waste of time.

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 12:15 pm
by Schol-R-LEA
I did say I would give you some sort of review and advice on the current state of Dixium, and while I only have a few comments so far, mostly suggestions rather than fixes, here's a start:
  • You included the object files for the project in the repository. Not quite a mistake, but it isn't necessary - you generally only want to check in the source code and other things which get edited by you rather than generated by the compiler or assembler.
  • Similarly, the headers are duplicated in the top level of the repo, which shouldn't be necessary unless I am missing something. If nothing else, it is confusing, and leads to the possibility that a fix done on one copy might not get applied to the other.
  • While it is by no means mandatory, the usual practice in C and C++ is to have all the header files, and only the header files, directly in the main include directory, and have the code they declare in their own directories elsewhere. Whether this would work better for you or not is your decision.
  • As I had pointed out earlier, the multiboot stub sets the stack pointer to the label marking the top of the stack (a point in memory below the allocated stack memory), rather than the bottom of it.
  • You use the name "stdio.h" for the console I/O code header. While this again isn't a mistake per se, it might be confusing to someone else reading this code, especially since it is actually console-focused rather than streaming. I would recommend using a name like "kconsole.h" instead, and similarly renaming the other header names and their functions' names (or at least prepending them with a 'k' to make it clear that they are part of the kernel code) as well, but that's a suggestion rather than a criticism.

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 3:09 pm
by NunoLava1998
The book, if you want to know (read until page 65. learned that

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(pointertoseventyone)
}
would print the memory location of "seventyone", but

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(*pointertoseventyone)
}
would print "71", for example. there's not many new things i learned there, actually. 360 page book, very useful).

is:
Image

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 3:38 pm
by NunoLava1998
Defined it cor-

Code: Select all

kernel.o: In function `terminal_writestring':
kernel.c:(.text+0x160): undefined reference to `strlen'
This doesn't work?:

Code: Select all

char strlen(const char[]);
umm...
Here's my make.bat file log/what it returned:

Code: Select all

Installation process. Please add nasm, dd and ghost-i686-elf-tools to your "PATH" variable.
Current PATH:
C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;I:\ghost-i686-elf-tools\bin;C:\Users\(insert my username here)\AppData\Local\Microsoft\WindowsApps
Press any key to continue.
DOING THE BOOT.ASM COMPILATION
Any errors will be reported.
DOING THE KERNEL.C COMPILATION
Above with warnings ignored. Below with warnings not ignored. If there is nothing on both, your OS is practically perfect.
In file included from kernel.c:5:0:
include/kbd/kbd.c: In function 'getkey':
include/kbd/kbd.c:70:6: warning: variable 'key' set but not used [-Wunused-but-set-variable]
  int key;
      ^
kernel.c: In function 'kernel_main':
kernel.c:10:2: warning: implicit declaration of function 'newlinef123' [-Wimplicit-function-declaration]
  newlinef123();
  ^
kernel.c:14:2: warning: passing argument 1 of 'terminal_writestring' makes pointer from integer without a cast [enabled by default]
  terminal_writestring(Key);
  ^
In file included from kernel.c:4:0:
include/tty/tty.c:54:6: note: expected 'const char *' but argument is of type 'int'
 void terminal_writestring(const char* data) {
      ^
kernel.c: At top level:
kernel.c:16:6: warning: conflicting types for 'newlinef123' [enabled by default]
 void newlinef123(void){
      ^
kernel.c:10:2: note: previous implicit declaration of 'newlinef123' was here
  newlinef123();
  ^
kernel.c: In function 'newlinef123':
kernel.c:17:15: warning: operation on 'terminal_row' may be undefined [-Wsequence-point]
  terminal_row = terminal_row++;
               ^
In file included from kernel.c:5:0:
include/kbd/kbd.c: In function 'getkey':
include/kbd/kbd.c:72:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
C++ mode, warnings not ignored.
In file included from kernel.c++:5:0:
include/kbd/kbd.c: In function 'short unsigned int getkey()':
include/kbd/kbd.c:70:6: warning: variable 'key' set but not used [-Wunused-but-set-variable]
  int key;
      ^
include/kbd/kbd.c:72:1: warning: no return statement in function returning non-void [-Wreturn-type]
 }
 ^
kernel.c++: In function 'void kernel_main()':
kernel.c++:10:14: error: 'newlinef123' was not declared in this scope
  newlinef123();
              ^
kernel.c++:14:26: error: invalid conversion from 'int' to 'const char*' [-fpermissive]
  terminal_writestring(Key);
                          ^
In file included from kernel.c++:4:0:
include/tty/tty.c:54:6: error:   initializing argument 1 of 'void terminal_writestring(const char*)' [-fpermissive]
 void terminal_writestring(const char* data) {
      ^
kernel.c++: In function 'void newlinef123()':
kernel.c++:17:31: warning: operation on 'terminal_row' may be undefined [-Wsequence-point]
  terminal_row = terminal_row++;
                               ^
LINKING...
If anything fails, check your code.
kernel.o: In function `terminal_writestring':
kernel.c:(.text+0x160): undefined reference to `strlen'
collect2.exe: error: ld returned 1 exit status
If there were no errors, everything went fine.

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 4:29 pm
by alexfru
NunoLava1998 wrote:The book, if you want to know (read until page 65. learned that

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(pointertoseventyone)
}
would print the memory location of "seventyone",
That can't be right. You're missing semicolons and printf()'s first argument must a pointer to a format string. Further, even if you fix that, it would still not print "would print the memory location of "seventyone"" because seventyone is not &seventyone.
The correct code after addressing all of the issues would be something like this:

Code: Select all

#include <stdio.h>
int main(void){
	int seventyone = 71;
	int *pointertoseventyone = &seventyone;
	printf("%p\n", (void*)pointertoseventyone);
	return 0;
}
NunoLava1998 wrote: but

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(*pointertoseventyone)
}
would print "71", for example.
Likewise, the correct code would be something like this:

Code: Select all

#include <stdio.h>
int main(void){
	int seventyone = 71;
	int *pointertoseventyone = &seventyone;
	printf("%d\n", *pointertoseventyone);
	return 0;
}
If your book is teaching you to write wrong code, you may want a better book. Otherwise, you should pay attention to details because C is not a forgiving language.

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 4:34 pm
by NunoLava1998
alexfru wrote:
NunoLava1998 wrote:The book, if you want to know (read until page 65. learned that

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(pointertoseventyone)
}
would print the memory location of "seventyone",
That can't be right. You're missing semicolons and printf()'s first argument must a pointer to a format string. Further, even if you fix that, it would still not print "would print the memory location of "seventyone"" because seventyone is not &seventyone.
The correct code after addressing all of the issues would be something like this:

Code: Select all

#include <stdio.h>
int main(void){
	int seventyone = 71;
	int *pointertoseventyone = &seventyone;
	printf("%p\n", (void*)pointertoseventyone);
	return 0;
}
NunoLava1998 wrote: but

Code: Select all

#include <stdio.h>
int main(){
	int seventyone = 71;
	int *pointertoseventyone = seventyone
	printf(*pointertoseventyone)
}
would print "71", for example.
Likewise, the correct code would be something like this:

Code: Select all

#include <stdio.h>
int main(void){
	int seventyone = 71;
	int *pointertoseventyone = &seventyone;
	printf("%d\n", *pointertoseventyone);
	return 0;
}
If your book is teaching you to write wrong code, you may want a better book. Otherwise, you should pay attention to details because C is not a forgiving language.
I do remove %d\n, but it is there.
EDIT: You're correct, i just forget some stuff and remove some stuff, but the book shows the correct examples.

Re: Why is ld complaining?

Posted: Sat Nov 19, 2016 7:34 pm
by Schol-R-LEA
NunoLava1998 wrote:I do remove %d\n, but it is there.
Hmmn, that is phrased a bit awkwardly, and ambiguously as well. Do you mean that the code was in the book, but you omitted it in the code you were compiling (whether intentionally or not), or that it was in both the book and the actual compiled code but was somehow dropped when you pasted or re-typed it into the message board's editor?

If the former, did you omit it deliberately, or by mistake, and did you try it with the code exactly as given as well?

If the latter, were you using cut and paste, or re-typing it, and if pasting it, did you do anything else that might have caused it to get dropped (again, whether intentionally or accidentally)?

My assumption is that it was accidental, regardless of where it took place; however, if it was intentional, I am curious as to the reason for it.

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 1:06 am
by osdever
I think that moderators should close this thread. It's waste of time to teach and/or help him.

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 4:32 am
by NunoLava1998
Schol-R-LEA wrote:
NunoLava1998 wrote:I do remove %d\n, but it is there.
Hmmn, that is phrased a bit awkwardly, and ambiguously as well. Do you mean that the code was in the book, but you omitted it in the code you were compiling (whether intentionally or not), or that it was in both the book and the actual compiled code but was somehow dropped when you pasted or re-typed it into the message board's editor?

If the former, did you omit it deliberately, or by mistake, and did you try it with the code exactly as given as well?

If the latter, were you using cut and paste, or re-typing it, and if pasting it, did you do anything else that might have caused it to get dropped (again, whether intentionally or accidentally)?

My assumption is that it was accidental, regardless of where it took place; however, if it was intentional, I am curious as to the reason for it.
The book has "%d\n". However, i intentionally removed it. I made a example.

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 4:52 am
by iansjack
NunoLava1998 wrote:The book has "%d\n". However, i intentionally removed it. I made a example.
You made an error. I'm sure the book must have explained the purpose of the format string in printf().

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 9:51 am
by MichaelFarthing
I think there's a mistake in the quotation attribution there!
[This is the sort of situation where PMs are quite useful :? ]

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 11:43 am
by iansjack
There certainly is! Now corrected.

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 12:38 pm
by Schol-R-LEA
OK, I see you deleted the object files, that's not bad. I would recommend (if you haven't do so already) putting a .gitignore file in your working (local) directory with the following masks, along with any others that you think you might need, which will prevent files matching those patterns from being checked in by git:

Code: Select all

*.o
*.O
*.obj
.sh
*.bak
*.*~
(The last two are masks for extensions used by some editors for backups and temporary files; e.g., if you edit kernel.c, when you save the changes the editor would rename the existing file as either kernel.bak or kernel.c~, and save the changed version as a new file.)

I also see you haven't checked in a Makefile, so I am wondering if you are using one; from what you said earlier, I assume you are using the file make.bat instead. In any case, I know several editors and IDEs have their own project file formats, so you might not find one useful, but if you need one, you can start with the one below. I had to make some guesses of the paths for your OS Specific Toolchain based on the error messages mentioned, so you will need to modify this somewhat, if not now hhen when as you add new files to the project (and/or fix the problems with the current layout). You should read the article on Makefiles in order to understand this before you use it, as I have no way of knowing of this will work on your system as-is. Hopefully, I haven't made too many horrible errors, though if some like Solar or Brendan can review it, I would be grateful.

Code: Select all

#first, set the paths where the files are to be found
# binary toolchain
BIN := I:/ghost-i686-elf-tools/bin
#
# Dixium source code path - set it to the current directory the Makefile is in
SRCPATH := . 
# system include headers
INCPATH := $(SRCPATH)/include:$(SRCPATH)/include/tty:$(SRCPATH)/include/kbd

# source code files required by the build
SRCFILES := $(SRCPATH)/kernel.c $(SRCPATH)/boot.asm $(INCPATH)/kbd/kbd.c $(INCPATH)/tty/tty.c

# header files required for the build
INCFILES := stdio.h stdlib.h include/tty/strings.h include/tty/vga.h include/kbd/stdio.h

# non-code files which should always be included with the code files
AUXFILES := Makefile README.md LICENSES

# list all the files that need to be distributed for the build, not
#including temporary files such as object or dependency files
DISTFILES := $(SRCFILES) $(INCFILES) $(AUXFILES)

# define the toolchain tools to be used and their settings
CC := $(BIN)/gcc
WARNINGS := -Wall -Wextra -pedantic -Wshadow -Wpointer-arith -Wcast-align \
            -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations \
            -Wredundant-decls -Wnested-externs -Winline -Wno-long-long \
            -Wuninitialized -Wconversion -Wstrict-prototypes
# set the compile options used by all builds
CFLAGS := -g -O2 -std=c99 $(WARNINGS) -ffreestanding -I$(INCPATH)

# compile and/or link the sources into the files given by the target names
ASSEMBLE := nasm -t ELF
BUILD := $(CC) $(CFLAGS) -c $@
LINK := $(CC) $(CFLAGS) -o $@

#### build rules
#############

all: dixium

dixium: kernel kbd tty
	$(LINK) $(OBJFILES)

kernel: boot.asm kernel.c
	$(ASSEMBLE) boot.asm
	$(BUILD) kernel.c

kbd: $(INCPATH)/kbd/kbd.c
	$(BUILD) $(INCPATH)/kbd/kbd.c

tty: $(INCPATH)/tty/tty.c
	$(BUILD) $(INCPATH)/kbd/tty.c

clean:
	del *.o

Re: Why is ld complaining?

Posted: Sun Nov 20, 2016 1:05 pm
by Schol-R-LEA
Continuing my advice, I should note that while you declare strlen() in the include/tty/string.h header, it isn't implemented anywhere as far as I can find. You can't link what doesn't exist.

Looking at include/kbd/kbd.c, I see the following inclusions:

Code: Select all

#define _GNU_SOURCE
#include "stdio.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
Now, I have already mentioned that you probably should use a different name for the console keyboard file, but aside from that, I see two issues. First, the flag _GNU_SOURCE implies that the file is part of a GNU library, which would not be the case here. Thus, I would drop that. Second, since the stdbool.h, stddef.h, and stdint.h files are meant to wrap the system-specific types and definitions in a portable wrapper, you would need your own versions of each of those, AFAIK. These would have to be in your build's standard include path, which should have it's own version of these files. More importantly, they should be included in the repo's include directory - even if the version you are using are the same as the ones distributed with your original copy of GCC, they should be at the very least ready to be tailored to your OS, if necessary.

I would also recommend moving the functions inb() and outb() to another file, as they will almost certainly be useful elsewhere in the OS project. Since they are declared as inline, this would be a case where it is reasonable to put them in a header, something you normally wouldn't do with functions but is typical practice for inline functions.