Problem with string literlals

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Problem with string literlals

Post by Peterbjornx »

I have just started working on a simple kernel, so far everything works except string literals,
when i try to print a string literal either i get a lot of nonsense characters , or it doesnt print anything, while i can print a manually filled char array using the same function:

Code: Select all

#include "init.h"
#include "text_video.h"
#include "x86.h"
void kmain( void* mbd, unsigned int magic ) {
	char *hello_literal = "Hello\n\0";
        char hello_array[7];
        hello_array[0] = 'H';
        hello_array[1] = 'e';
        hello_array[2] = 'l';
        hello_array[3] = 'l';
        hello_array[4] = 'o';
        hello_array[5] = '\n';
        hello_array[6] = '\0';
	init_video();
	clear_video();
	kputch('P');
        kprint(hello_array);
        kprint(hello_literal);
}
Output: PHello

My toolset is Microsoft Visual C++ Express Edition 2010 and MinGW32 objcopy to convert PE to flat binary

What could be the cause of this behaviour?
User avatar
JamesM
Member
Member
Posts: 2935
Joined: Tue Jul 10, 2007 5:27 am
Location: York, United Kingdom
Contact:

Re: Problem with string literlals

Post by JamesM »

Hi,

I honestly don't know about MS Visual Studio, but if this were GCC the problem would be to do with your linker script. String literals go in the .rodata section, which in some linker scripts doesn't get linked into .data properly.

Double check your linker script in case this applies to you.

James
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

visual studio doesnt use a link script, but the map file it generates is :

Code: Select all

Preferred load address is 00100000

 Start         Length     Name                   Class
 0001:00000000 00000796H .text                   CODE
 0002:00000000 0000008cH .bss                    DATA

  Address         Publics by Value              Rva+Base       Lib:Object

 0001:00000000       ___multiboot_entry__@0     00100400 f   loader.obj
 0001:00000040       ?get_BDA@@YGPAUbda_td@@XZ  00100440 f   bios.obj
 0001:00000050       ?init_descriptor_tables@@YGXXZ 00100450 f   descriptor_tables.obj
 0001:000001c0       ?kmain@@YGXPAXI@Z          001005c0 f   init.obj
 0001:000001f0       ?memcpy@@YGPAXPAXPBXI@Z    001005f0 f   memcpy.obj
 0001:00000240       ?memsetw@@YGPAXPAXHI@Z     00100640 f   memsetw.obj
 0001:00000280       ?strlen@@YGIPBD@Z          00100680 f   strlen.obj
 0001:000002c0       ?is_monochrome@@YGHXZ      001006c0 f   text_video.obj
 0001:000002e0       ?get_page_length@@YGHXZ    001006e0 f   text_video.obj
 0001:00000310       ?get_text_video_memory@@YGPCUsc_s@@XZ 00100710 f   text_video.obj
 0001:00000330       ?_putch@@YGXDPAUvci_s@@@Z  00100730 f   text_video.obj
 0001:000003b0       ?write_crtc_register@@YGXDD@Z 001007b0 f   text_video.obj
 0001:000003e0       ?handle_escape@@YGXD@Z     001007e0 f   text_video.obj
 0001:000003f0       ?move_cursor@@YGXXZ        001007f0 f   text_video.obj
 0001:00000430       ?switch_vc@@YGXH@Z         00100830 f   text_video.obj
 0001:00000490       ?__putch@@YGXDPAUvci_s@@@Z 00100890 f   text_video.obj
 0001:00000620       ?clear_video@@YGXXZ        00100a20 f   text_video.obj
 0001:00000660       ?kputch@@YGXD@Z            00100a60 f   text_video.obj
 0001:000006a0       ?kprint@@YGXPAD@Z          00100aa0 f   text_video.obj
 0001:000006e0       ?init_video@@YGXXZ         00100ae0 f   text_video.obj
 0001:00000780       ?cli@@YGXXZ                00100b80 f   x86.obj
 0001:00000790       ?sti@@YGXXZ                00100b90 f   x86.obj
 0002:00000000       ?gdt_ptr@@3Ugdt_ptr_struct@@A 00100c00     descriptor_tables.obj
 0002:00000008       ?gdt_entries@@3PAUgdt_entry_struct@@A 00100c08     descriptor_tables.obj
 0002:00000030       ?all_vcs@@3PAUvci_s@@A     00100c30     text_video.obj
 0002:00000088       ?current_vc@@3PAUvci_s@@A  00100c88     text_video.obj

 entry point at        0000:00000000

 Static symbols

 0001:00000060       ?init_gdt@@YGXXZ           00100460 f   descriptor_tables.obj
 0001:000000f0       ?gdt_flush@@YGXI@Z         001004f0 f   descriptor_tables.obj
 0001:00000120       ?gdt_set_gate@@YGXHIIEE@Z  00100520 f   descriptor_tables.obj
 0001:00000590       ?scroll@@YGXPAUvci_s@@@Z   00100990 f   text_video.obj
and the assembly listing for another try at it is :

Code: Select all

; Listing generated by Microsoft (R) Optimizing Compiler Version 16.00.21003.01 

	TITLE	C:\Users\Peter Bosch\documents\visual studio 2010\Projects\Codename PBX\Codename PBX\init.c
	.686P
	.XMM
	include listing.inc
	.model	flat

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC	??_C@_0M@KPLPPDAC@Hello?5World?$AA@		; `string'
PUBLIC	?kmain@@YGXPAXI@Z				; kmain
EXTRN	?kprint@@YGXPAD@Z:PROC				; kprint
EXTRN	?clear_video@@YGXXZ:PROC			; clear_video
EXTRN	?init_video@@YGXXZ:PROC				; init_video
;	COMDAT ??_C@_0M@KPLPPDAC@Hello?5World?$AA@
; File c:\users\peter bosch\documents\visual studio 2010\projects\codename pbx\codename pbx\init.c
CONST	SEGMENT
??_C@_0M@KPLPPDAC@Hello?5World?$AA@ DB 'Hello World', 00H ; `string'
; Function compile flags: /Odtp
CONST	ENDS
;	COMDAT ?kmain@@YGXPAXI@Z
_TEXT	SEGMENT
_mbd$ = 8						; size = 4
_magic$ = 12						; size = 4
?kmain@@YGXPAXI@Z PROC					; kmain, COMDAT

; 4    : void kmain( void* mbd, unsigned int magic ) {

  00000	55		 push	 ebp
  00001	8b ec		 mov	 ebp, esp

; 5    : 	init_video();

  00003	e8 00 00 00 00	 call	 ?init_video@@YGXXZ	; init_video

; 6    : 	clear_video();

  00008	e8 00 00 00 00	 call	 ?clear_video@@YGXXZ	; clear_video

; 7    : 	kprint("Hello World");

  0000d	68 00 00 00 00	 push	 OFFSET ??_C@_0M@KPLPPDAC@Hello?5World?$AA@
  00012	e8 00 00 00 00	 call	 ?kprint@@YGXPAD@Z	; kprint

; 8    : }

  00017	5d		 pop	 ebp
  00018	c2 08 00	 ret	 8
?kmain@@YGXPAXI@Z ENDP					; kmain
_TEXT	ENDS
END
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Problem with string literlals

Post by gerryg400 »

Code: Select all

CONST   SEGMENT
??_C@_0M@KPLPPDAC@Hello?5World?$AA@ DB 'Hello World', 00H ; `string'
; Function compile flags: /Odtp
CONST   ENDS
It looks like your string is going into the CONST segment. You need to make sure that segment is loaded.

- gerryg400
If a trainstation is where trains stop, what is a workstation ?
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

How would i do that, i'm using GRUB and

Code: Select all

dd(0x1BADB002)              			
 ; magic
                    dd(1 << 16)                   			  ; flags - aout-kludge
                    dd(-(0x1BADB002 + (1 << 16)))   		  ; checksum
                    dd(0x100000)            	  		      ; header_addr
                    dd(0x100000)          				      ; load_addr
                    dd(0x0)           					      ; load_end_addr
                    dd(0x0)             					  ; bss_end_addr
                    dd(0x100000 + 0x20)         		      ; entry_addr
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Problem with string literlals

Post by neon »

Hello,

Use the Bochs Debugger and make sure your string is where its expected to be at. I wonder how you are using objcopy to convert it to a flat binary - perhaps that might be where the problem is at.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

i have a custom build step:

Code: Select all

objcopy.exe /I pe-i386 /O binary kernel.dll kernel.bin
, when i look in the kernel.bin with a hex editor i see my strings there so they are getting converted.
gerryg400
Member
Member
Posts: 1801
Joined: Thu Mar 25, 2010 11:26 pm
Location: Melbourne, Australia

Re: Problem with string literlals

Post by gerryg400 »

This problem will be simple for you to diagnose. But think about it your plan of attack.

e.g.
1. Create a simple version without any confusing code. e.g. only have one printk, only have one string so you can understand the code more easily.

2. Inspect the actual binary that you are loading code with a disassembler or debugger. Work through the logic line by line. Check all addresses in assembler code.

3. You cannot fix a problem unless you know what the problem is. 'String not appearing' is not a problem, it is a symptom. The problem might be 'The linker links to wrong address' OR 'the compiler puts the sting in the wrong segment'. When you know the problem you can fix it. It's even possible that there is a bug in your tool-chain.

Sometimes people on osdev will recognise a symptom and be able to give you a solution right away, but really, you need to learn how to diagnose these problems yourself. I can guarantee there will be many more problems. Any study you do now will not be wasted.

- gerryg400
If a trainstation is where trains stop, what is a workstation ?
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

What i found is that it nicely pushes the char * to the stack, with the right address (0x00101600), and that that mapping gets translated to binary fine
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

Well, after i checked the bin file again i saw that instead of keeping the string at 0x101A00 objcopy moved it to 0x101600 without chainging the pointer, and i couldnt get that to work with ms linker so i made a build step for GNU ld in my visual studio system but the data section pointers are off by 4 bytes,any idea on how i could move a section up 4 bytes?
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Re: Problem with string literlals

Post by neon »

Hello,

I personally have never mixed the MSVC toolchain with GNU tools so I cannot offer help. However I do want to mention that you do not need to use a flat binary kernel in order for GRUB to boot it. Thus their are alternative methods to get this working.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

I know, but when i try to run a PE executable linked by the microsoft linker, i get a grub error that it tried to read a block outside of the partition
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Problem with string literlals

Post by Gigasoft »

The problem is in your Multiboot header. You have header_addr set to 0x100000, where the correct address is probably 0x100400. You should set both header_addr and entry_addr to the correct labels instead of writing out the physical addresses you think they'll be at.

It should be possible to skip the objcopy step if you use /ALIGN:16 when linking. An align value below 4096 will create a flat file which can be used directly. However, this also means that uninitialized data will be included in the file. You can remove the extra zeros manually and have your code check the section headers to find any uninitialized data which it should zero out. Or, you could write a program that finds the uninitialized part of the .data segment and places the correct size in the Multiboot header before you objcopy it.
Peterbjornx
Member
Member
Posts: 116
Joined: Thu May 06, 2010 4:34 am
Libera.chat IRC: peterbjornx
Location: Leiden, The Netherlands
Contact:

Re: Problem with string literlals

Post by Peterbjornx »

of course i change 0x100000 to 0x100400, but thanks for the /ALIGN trick, ill try that once i get VS2010 installed on this pc
Post Reply