[C] Problem with read value of ptr by calculated ptr

Programming, for all ages and all languages.
Post Reply
nintyfan
Posts: 23
Joined: Wed Nov 07, 2018 10:15 am

[C] Problem with read value of ptr by calculated ptr

Post by nintyfan »

Code: Select all

/*
 KISS'EM - a little operating system.
 Copyright (C) 2018 Sławomir Lach <[email protected]>
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/

#include "../Include/types.h"
#define YES 1
#define NO 0
// For nice mode only
// Mixed mode is provided to allow handle problems before messages subsystem was initialized. You must take in mind, nice mode uses messages subsystem, so it will also depends probably on console module.
#define MIXED 2

#define DEBUG_ENABLED NO
// Change to no if there's problem with console module
#define ALLOW_NICE_MESSAGES YES

#ifndef HELPER_INCLUDED
#error To use debug header you must include helper
#endif

#if DEBUG_ENABLED == 0

#ifdef __DEBUG__
#undef __DEBUG__
#endif

#endif

#ifdef __DEBUG__
#define __MODULE_DEBUG_INIT
#define __print_int(x) { \
int stcount; \
int count = 0;\
int y = x; \
if (y == 0) { \
  \
  *__DEBBUGED___dbA = '0'; \
  ++__DEBBUGED___dbA; \
  ++__DEBBUGED___dbA; \
} \
else { while (y) { \
  ++count; y = y / 10;} \
  y = x; stcount = count;\
  if ((__DEBBUGED___dbA - ((char*)0xB8000)) + count > 80 * 25 * 2) { \
    __DEBBUGED___dbA = 0xB8000; \
  } \
  --count; \
  while (y) { \
    __DEBBUGED___dbA[count * 2] = (char)(y % 10 + '0'); --count; y = y / 10;} \
    __DEBBUGED___dbA += stcount * 2 ;} \
}  
#define ____NO_DEBBUGED__ \
char __DEBBUGED__color = 'A'; \
char* __DEBBUGED___dbA = ((char*)0xB8000); 
#define ____DEBBUGED__ \
char __DEBBUGED__color = 'A'; \
char* __DEBBUGED___dbA = ((char*)0xB8000); 
#define __print_debug_info { if (__IS_DEBBUGED__) {if (__DEBBUGED___curr > 'Z') __DEBBUGED___curr = 'A'; *__DEBBUGED___dbA = __DEBBUGED___curr; ++__DEBBUGED___dbA ; *__DEBBUGED___dbA = __DEBBUGED__color;++__DEBBUGED___dbA; print_int(__COUNTER__) ; ++__DEBBUGED___dbA ; ++__DEBBUGED___dbA;  ++__DEBBUGED___curr;  } }
#define __putsD(x) do { if (__IS_DEBBUGED__) {char *a = x; while ('\0' != *a) {*__DEBBUGED___dbA = *a; ++a; ++__DEBBUGED___dbA; ++__DEBBUGED___dbA;} ++__DEBBUGED___dbA; ++__DEBBUGED___dbA;} } while (0)
#define __clsD \
{ \
  if (__IS_DEBBUGED__) { \
    int i = 0;\
    for (; i < 80 * 25 * 2;  ++i) *((char*)(0xB8000 + i)) = ' '; \
      __DEBBUGED___dbA = (char*) 0xB8000; \
  } \
}


#if (ALLOW_NICE_MESSAGES == YES)
#define M____DEBBUGED__ ;
#define M____NO_DEBBUGED__ ; 
#define M__print_int(x) ;
#define M__print_debug_info ;
#define M__putsD(x)  ;
#define M__clsD ;
#else

#define M____DEBBUGED__ ____DEBBUGED__
#define M____NO_DEBBUGED__ ____NO_DEBBUGED__
#define M__print_int(x) __print_int(x)
#define M__print_debug_info __print_debug_info 
#define M__putsD(x)  __putsD(x)
#define M__clsD __clsD
#endif

#if (defined DRIVER_messages_NUMBER) && ((ALLOW_NICE_MESSAGES == YES) || (ALLOW_NICE_MESSAGES == MIXED))
  static void (*__DEBUG__global_print_fnc)(int fmt, void *parameters) = 0;
  static void (*__DEBUG__global_malloc_fnc)(int size) = 0;
  
#define __NO_DEBBUGED__  M____NO_DEBBUGED__;   char __IS_DEBBUGED__ = 0; char __DEBBUGED___curr = 'A';
#define __DEBBUGED__   M____DEBBUGED__;  char __IS_DEBBUGED__ = 1; char __DEBBUGED___curr = 'A'; putsD(KISS_STRING(__FILE__)); putsD(KISS_STRING(__FUNCTION__));
#define putsD(x) { M__putsD(x); if (__IS_DEBBUGED__ && *((void**)KISS_POINTER(&__DEBUG__global_print_fnc)))  { ((*(void(**)(int, intptr_t *))KISS_POINTER(&__DEBUG__global_print_fnc)))(-1, x); } }
#define print_int(x) { M__print_int(x); if (__IS_DEBBUGED__ && *((void**)KISS_POINTER(&__DEBUG__global_print_fnc))){  ((*(void(**)(int, intptr_t *))KISS_POINTER(&__DEBUG__global_print_fnc)))(-2, x); } }
  /* TODO: We need to free this memory */
#define print_debug_info   {M__print_debug_info;  if (__IS_DEBBUGED__ && *((void**)KISS_POINTER(&__DEBUG__global_print_fnc)) && *((void**)KISS_POINTER(&__DEBUG__global_malloc_fnc))) {intptr_t *parameters =   ((*(void*(**)(int))KISS_POINTER(&__DEBUG__global_malloc_fnc)))(sizeof(*parameters) * 3); if (0 != parameters) { parameters[0] = KISS_STRING("%c %d");parameters[1] = __DEBBUGED___curr; parameters[2] = __COUNTER__;   ((*(void(**)(int, intptr_t *))KISS_POINTER(&__DEBUG__global_print_fnc)))(-3, parameters);  } } };
#ifdef DRIVER_utils_NUMBER
#define MODULE_DEBUG_INIT *((void**)KISS_POINTER(&__DEBUG__global_print_fnc)) = dr[DRIVER_messages_NUMBER].get_export_tables()->api_version_exports->symbols[0].procedure; if (dr[DRIVER_utils_NUMBER].get_export_tables) *((void**)KISS_POINTER(&__DEBUG__global_malloc_fnc)) = dr[DRIVER_utils_NUMBER].get_export_tables()->api_version_exports->symbols[1].procedure;
#else
#define MODULE_DEBUG_INIT *((void**)KISS_POINTER(&__DEBUG__global_print_fnc)) = dr[DRIVER_messages_NUMBER].get_export_tables()->api_version_exports->symbols[0].procedure;
#endif
#else
#define MODULE_DEBUG_INIT
#define print_int(x) __print_int(x)
#define __NO_DEBBUGED__ ____NO_DEBBUGED__; char __IS_DEBBUGED__ = 0;  char __DEBBUGED___curr = 'A';
#define __DEBBUGED__ ____DEBBUGED__; char __IS_DEBBUGED__ = 1;char __DEBBUGED___curr = 'A'; M__putsD(KISS_STRING(__FILE__)); M__putsD(KISS_STRING(__FUNCTION__));
#define print_debug_info __print_debug_info
#define putsD(x) __putsD(x)
#define clsD  M__clsD
#endif
#else  
#define MODULE_DEBUG_INIT
#define __DEBBUGED__ 
#define __NO_DEBBUGED__
#define print_int(x)
#define print_debug_info
#define putsD(x)
#define clsD
#endif  
I'm still novice programmer and have trouble. Above I attached code of my os' debug module. Problem is inside if statement. As you can see, when module/C file have __DEBUG__ defined before including debug.h, I offer many debugging possibilities. Because I try to write os (kernel) as modular as possible, I updated pointer to some needed procedures, when there's macro called MODULE_DEBUG_INIT subsitution inside some proc of module. But..,. When I don't update these two variables (__DEBUG__global_print_fnc, __DEBUG__global_malloc_fnc), it may cause jump into not initialized memory (I think to 0 address). How to properly check if these variables are initialized?

I must calculate address to these variables, because modules are loaded by GRUB2 and I don't known how to compile position independent executable and make my kernel aware of this. Solution is simple: send pointer to start of module in memory via message/procedure call, so module can calculates position of each global variable.
nullplan
Member
Member
Posts: 1733
Joined: Wed Aug 30, 2017 8:24 am

Re: [C] Problem with read value of ptr by calculated ptr

Post by nullplan »

"I'm a novice programmer and need help writing a kernel" is sort of like "I'm a novice climber and need help halfway up Mt. Everest". Yeah, I can see that you would. You have created an awful tangled web I gave up on understanding halfway through. That code would not be out of place at the IOCCC, you know? What is with all the underscores? Why are you using at least four of the things in every name? And that is just the debug print code!

If you don't know how to use position independent code, then either get some experience with it or link everything together in a single kernel binary. Modularity doesn't necessarily have anything to do with the created binaries. It is more of a source-level property. I can tell you that a memory model including position-independent modules before paging is even enabled will be a big problem, way bigger than relocating a single statically linked kernel image after paging is enabled.

As for the main question: You can't. There is precisely one pointer, the null pointer, that is definitely invalid, but if a pointer has an arbitrary value, there is no way to know whether it is valid or not.
Carpe diem!
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: [C] Problem with read value of ptr by calculated ptr

Post by bloodline »

nullplan wrote:Yeah, I can see that you would. You have created an awful tangled web I gave up on understanding halfway through.
You did well, I can’t follow any of this.

I think the OP needs to start again and avoid using the #define directive...
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: [C] Problem with read value of ptr by calculated ptr

Post by PeterX »

bloodline wrote:I think the OP needs to start again and avoid using the #define directive...
I think so, too. What are all the conditional compilation statements good for? If you want to debug, then simply do so. One level of "ifdef"s should be enough. I would prefer none of them at all.

Greetings
Peter
User avatar
iansjack
Member
Member
Posts: 4662
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: [C] Problem with read value of ptr by calculated ptr

Post by iansjack »

I can't imagine a novice programmer writing this code. Copy-paste perhaps, but not write.
nintyfan
Posts: 23
Joined: Wed Nov 07, 2018 10:15 am

Re: [C] Problem with read value of ptr by calculated ptr

Post by nintyfan »

Hi.

I known double underscores are reserved for C extensions, but I decided to use it to avoid use same symbols in different matters, especially by other programmers.

Conditional statements are necessary, because I wrote separate console module and need to redirect all messages to it. That mean I cannot debug console module itself or it's strictly not recommencement. Redirection was used to avoid case, where normal messages overlaps debug or vice versa and to made possible to debug many functions at once. Conditions checks if pointer was initialized by MODULE_DEBUG_INIT macro.
PeterX
Member
Member
Posts: 590
Joined: Fri Nov 22, 2019 5:46 am

Re: [C] Problem with read value of ptr by calculated ptr

Post by PeterX »

nintyfan wrote:Hi.

I known double underscores are reserved for C extensions, but I decided to use it to avoid use same symbols in different matters, especially by other programmers.

Conditional statements are necessary, because I wrote separate console module and need to redirect all messages to it. That mean I cannot debug console module itself or it's strictly not recommencement. Redirection was used to avoid case, where normal messages overlaps debug or vice versa and to made possible to debug many functions at once. Conditions checks if pointer was initialized by MODULE_DEBUG_INIT macro.
I don't understand what you are trying to do. But I am sure you are on the totally wrong track. Your code is nonsense and nobody needs to write such a code. You are thinking too complicated. You better get a thorough course/seminar from a computer science/programming teacher.
User avatar
bloodline
Member
Member
Posts: 264
Joined: Tue Sep 15, 2020 8:07 am
Location: London, UK

Re: [C] Problem with read value of ptr by calculated ptr

Post by bloodline »

nintyfan wrote:Hi.

I known double underscores are reserved for C extensions, but I decided to use it to avoid use same symbols in different matters, especially by other programmers.
Unless they are linking in with your source code that shouldn't matter?

How are you exposing your kernel interface to the userspace?
Conditional statements are necessary, because I wrote separate console module and need to redirect all messages to it. That mean I cannot debug console module itself or it's strictly not recommencement. Redirection was used to avoid case, where normal messages overlaps debug or vice versa and to made possible to debug many functions at once. Conditions checks if pointer was initialized by MODULE_DEBUG_INIT macro.
This is overly complex, you'll spend more time debugging your debugging code than actually writing any code...
Surely you just need some conditionally compiled print functions to your main console (or better debugging serial)...

I have a windowing GUI brought up very early in the boot process, that has a console for the boot process, and a second console for the system/debugging output... if you don't have a GUI that, you could have two terminal buffers and set up a hot key to switch between terminal displays.
CuriOS: A single address space GUI based operating system built upon a fairly pure Microkernel/Nanokernel. Download latest bootable x86 Disk Image: https://github.com/h5n1xp/CuriOS/blob/main/disk.img.zip
Discord:https://discord.gg/zn2vV2Su
Post Reply