OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 6:02 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2
Author Message
 Post subject: Re: Interrupt directive ignored
PostPosted: Wed Oct 04, 2017 2:58 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
Korona wrote:
stdint.h is provided by the compiler, its part of C's freestanding subset.
Still simpler to just write my own than to try to get the compiler to let me include its version (and deal with any incompatibilities that come up).
Korona wrote:
Code:
   current_offset = 0;\
   while (*((uint32_t*) (&&isr_start + current_offset)) != 0x01234567)\
   {\
      current_offset++;\
   }\
   *((uint32_t*) (&&isr_start + current_offset)) = irq_handler;

EDIT: Oh, I see, it's patching the assembly at runtime because you didn't use the correct constraint for it to accept static function pointers (IIRC it's p with a c modifier). Oh dog. Not only will this fail if your code segment is write-protected (which it really should be), it is also daily WTF worthy.

Write your stubs in a real assembler file, not in some kind of hacky and unreadable inline assembler. If you really want to write it in inline assembler, use GCC's unit-level assembly extension.
I can't really remember everything that went on in there. I wasn't doing this patching thing originally, but I was having difficulty getting it to compile after I changed something else (I can't remember what or why it made it refuse to compile) so I just hacked this together because my main priority at the time was to get the interrupts to my interrupt dispatcher function and implement my kernel's interrupt API and get that working, without worrying too much about exactly how the interrupts get to the interrupt dispatcher. I can always change this later, it's about three or four lines of assembler to get the interrupts to the interrupt dispatcher and the rest is just plain C code.

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Wed Oct 04, 2017 3:10 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
I seem to remember that the problem there was that the address of irq_handler either wasn't known or couldn't be referenced at compile time after I changed the compilation flags that I was using or changed something in my linker script. To be honest something usually breaks whenever I fiddle with the linker script, so I prefer to leave it alone if possible. At the time I remember having written another block of code somewhere that took a few hours, then spending another hour trying to figure out why it wouldn't compile, then another half an hour fiddling with the linker script, then this issue came up, so at that point I suppose I just figured "do some hack thing here to get this to work and sort it out later because I want to compile and test this thing now". It's hackish but to be honest I don't see any way that this could fail (at first glance it appears that it might fail if uninitialised memory happens to contain 0x01234567 but on further inspection it doesn't because it will always find the placeholder value before it reaches uninitialised memory).

Also how am I supposed to write-protect the code segment in a flat memory model because code and data are in the same place (0 GB - 4 GB)? I'm not using paging at the moment, that's on the todo list for whenever I sort out memory protection, privilege levels, and general security (as with everything else that I skip, my aim is to try out and experiment with a concept for OS design, not get hung up on implementation details, so if it works well enough for me to experiment with it then I'm happy with it).

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Thu Oct 05, 2017 11:24 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
onlyonemac wrote:
Still simpler to just write my own than to try to get the compiler to let me include its version (and deal with any incompatibilities that come up).

It's not simpler to write your own, because using the compiler's stdint.h is one line of code:
Code:
#include <stdint.h>
Since it's a standard header, there won't be any incompatibilities as long as you're using it in the intended way.

onlyonemac wrote:
It's hackish but to be honest I don't see any way that this could fail (at first glance it appears that it might fail if uninitialised memory happens to contain 0x01234567 but on further inspection it doesn't because it will always find the placeholder value before it reaches uninitialised memory).

At least two of the things you're doing in those few lines of code are undefined behavior, so it can easily fail at any time for no reason. You're lucky it works in the first place.

onlyonemac wrote:
Also how am I supposed to write-protect the code segment in a flat memory model because code and data are in the same place (0 GB - 4 GB)?

You can abuse paging (or segmentation) to add write-protection while keeping virtual addresses equal to physical addresses, but that would be a waste of time if you're just going to replace it when you implement paging for memory mapping.


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Thu Oct 05, 2017 2:10 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
Octocontrabass wrote:
It's not simpler to write your own, because using the compiler's stdint.h is one line of code:
Code:
#include <stdint.h>
Since it's a standard header, there won't be any incompatibilities as long as you're using it in the intended way.
So first I have to tell the compiler that I want it to search the system includes directory for this one file, when I've explicitly told it *not* to use system includes. Then I have to hope that the file is the same/compatible on another system that might be used for compiling the code. There's no reason not to write my own when I'm writing everything else and the rest of my code is self-contained in one project that doesn't depend on whatever files the system used for compilation happens to have available.

Also note that "standard header" is only relevant when you're using the "standard library". You can't just pull one header out of the standard library and expect it to always work in isolation. I am not using the standard library and have no intention of using it.
Octocontrabass wrote:
At least two of the things you're doing in those few lines of code are undefined behavior, so it can easily fail at any time for no reason. You're lucky it works in the first place.
Apart from overwriting the executable code (which is apparently bad even though I have multiple valid use cases for this), what part of looping through a section of initialised memory and replacing a specific value is undefined behaviour?

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Thu Oct 05, 2017 4:07 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
onlyonemac wrote:
So first I have to tell the compiler that I want it to search the system includes directory for this one file, when I've explicitly told it *not* to use system includes. Then I have to hope that the file is the same/compatible on another system that might be used for compiling the code. There's no reason not to write my own when I'm writing everything else and the rest of my code is self-contained in one project that doesn't depend on whatever files the system used for compilation happens to have available.

stdint.h is not part of the C standard library implementation. It is not in /usr/include. Instead, it is part of GCC. GCC provides it even if you build it --without-headers and compile --freestanding. This is actually covered in the C standard and designed for bare metal development.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Fri Oct 06, 2017 2:29 pm 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
Korona wrote:
stdint.h is not part of the C standard library implementation. It is not in /usr/include. Instead, it is part of GCC. GCC provides it even if you build it --without-headers and compile --freestanding. This is actually covered in the C standard and designed for bare metal development.
Whatever, I still don't see any reason not to write my own, when I'm writing everything else myself and designing my system to be independent of any particular compiler, language, or toolchain. What if someone is using a compiler other than gcc that doesn't include this header? Even if it's part of the standard, give me one good reason why I should specifically not write my own?

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Fri Oct 06, 2017 5:24 pm 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
There is no reason why you absolutely have to write your own but 1) techically it is undefined behavior if you replace it, also nothing bad happens in practice and 2) it ensures that it works correctly with all others components of the GCC toolchain (e.g. libgcc and libstdc++) and 3) it is unnecessary work and reinvents the wheel. 1) and 2) can of course be avoided if you're careful.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Fri Oct 06, 2017 11:51 pm 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
onlyonemac wrote:
Korona wrote:
I still don't see any reason not to write my own, when I'm writing everything else myself and designing my system to be independent of any particular compiler, language, or toolchain.

As you will be writing your own compiler, assembler, and linker you'll also be writing your own versions of all header files.


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sat Oct 07, 2017 6:03 am 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
iansjack wrote:
onlyonemac wrote:
I still don't see any reason not to write my own, when I'm writing everything else myself and designing my system to be independent of any particular compiler, language, or toolchain.
As you will be writing your own compiler, assembler, and linker you'll also be writing your own versions of all header files.
I don't know if you're being sarcastic but that is the idea, yes. One day, I might want to write my own compiler. I might even be using a language other than C. Just as my OS isn't dependant on existing filesystems (it has its own filesystem) or existing file formats (it will have wrappers for file formats that provide neutral interpretations of the data (e.g. applications will see all audio files as multiple uncompressed streams at a particular sampling rate and bit depth, no matter what the format of the underlying data is) so nothing except the wrapper modules is dependent on a particular file format) it also shouldn't be dependant on existing languages or compilers.

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sat Oct 07, 2017 6:47 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
I wasn't being sarcastic at all, just stating the obvious.


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sat Oct 07, 2017 2:32 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
onlyonemac wrote:
So first I have to tell the compiler that I want it to search the system includes directory for this one file, when I've explicitly told it *not* to use system includes.

You're using a cross-compiler, right? There's no "system includes directory" unless your compiler is targeted to a specific operating system. (Also, you shouldn't use -nostdinc, since that disables the freestanding headers in addition to the nonexistent system headers.)

onlyonemac wrote:
Then I have to hope that the file is the same/compatible on another system that might be used for compiling the code.

You don't have to worry about that. The freestanding headers are a dependency for countless C programs (even programs that are not freestanding), so any compiler that doesn't provide them or provides an incompatible version will have some obvious issues.

onlyonemac wrote:
There's no reason not to write my own when I'm writing everything else and the rest of my code is self-contained in one project that doesn't depend on whatever files the system used for compilation happens to have available.

Will you also be providing your own implementation of libgcc when GCC inevitably generates code that depends on it? Writing your own implementation of stdint.h is replacing a built-in part of the compiler in the same way.

onlyonemac wrote:
Also note that "standard header" is only relevant when you're using the "standard library". You can't just pull one header out of the standard library and expect it to always work in isolation.

Yes you can! That's why they're called "freestanding".

onlyonemac wrote:
Apart from overwriting the executable code (which is apparently bad even though I have multiple valid use cases for this), what part of looping through a section of initialised memory and replacing a specific value is undefined behaviour?

Overwriting executable code isn't necessarily bad, but a C program overwriting itself is undefined. The other piece of undefined behavior is your improperly aligned pointer conversion. A pointer to uint32_t must be aligned to the nearest sizeof(uint32_t) boundary.


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sun Oct 08, 2017 3:07 am 
Offline
Member
Member

Joined: Sat Mar 01, 2014 2:59 pm
Posts: 1146
Octocontrabass wrote:
You're using a cross-compiler, right? There's no "system includes directory" unless your compiler is targeted to a specific operating system. (Also, you shouldn't use -nostdinc, since that disables the freestanding headers in addition to the nonexistent system headers.)
No cross compiler. No need for a cross compiler when all I'm doing is outputting flat, self-contained, position-independent binaries.
Octocontrabass wrote:
Will you also be providing your own implementation of libgcc when GCC inevitably generates code that depends on it?
I have not yet encountered an issue with libgcc despite having used a large portion of the C language. I believe that either one of the compiler options that I'm using disables it or it's included statically and works cross-platform. I don't really care which because everything works fine.
Octocontrabass wrote:
Overwriting executable code isn't necessarily bad, but a C program overwriting itself is undefined. The other piece of undefined behavior is your improperly aligned pointer conversion. A pointer to uint32_t must be aligned to the nearest sizeof(uint32_t) boundary.
The C program is not overwriting itself. Of course I would never overwrite compiled C code because that's highly dependent on exactly what code the compiler produces. I'm overwriting an inline assembly section where I know exactly what's going on and exactly what binary code should be produced. I also don't know what your pointer alignment issue is, all I'm doing is overwriting one value in memory with a different value, so if the original value is aligned then the replacement will be aligned too and if the original value isn't aligned then that's not my fault because the original value was produced by inline assembly which should be aligned correctly by the assembler.

_________________
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sun Oct 08, 2017 4:51 am 
Offline
Member
Member

Joined: Thu May 17, 2007 1:27 pm
Posts: 999
x86 assembly has no alignment requirements, however the uint32_t does have them. If you really want to overwrite inline assembly use memcmp() to find the location and memcpy() to overwrite it. Or better, skip the memcpy() by encoding the instruction yourself, so that it is at a fixed offset from a known label.

For libgcc: Try 64 bit division on a i386 target.

_________________
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].


Top
 Profile  
 
 Post subject: Re: Interrupt directive ignored
PostPosted: Sun Oct 08, 2017 9:39 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
onlyonemac wrote:
No cross compiler. No need for a cross compiler when all I'm doing is outputting flat, self-contained, position-independent binaries.

That's exactly the situation where you need a cross-compiler. The system compiler is customized to produce binaries specifically for the host OS, and it may not be capable of producing self-contained binaries (e.g. because the code it emits may always require some external library). Only a cross-compiler is guaranteed to work correctly. I have to wonder if all the time you spent fighting with your linker is due to not using a cross-compiler.

onlyonemac wrote:
I have not yet encountered an issue with libgcc despite having used a large portion of the C language. I believe that either one of the compiler options that I'm using disables it or it's included statically and works cross-platform. I don't really care which because everything works fine.

It's impossible to disable libgcc, and libgcc does not work cross-platform if you're not using a cross compiler. You will care once you do something that requires libgcc, like the 64-bit division suggested by Korona.

onlyonemac wrote:
The C program is not overwriting itself. Of course I would never overwrite compiled C code because that's highly dependent on exactly what code the compiler produces. I'm overwriting an inline assembly section where I know exactly what's going on and exactly what binary code should be produced.

You're using labels that were defined in C, therefore you're overwriting compiled C code. GCC may emit the inline assembly somewhere other than where you expect it to be, and GCC may emit the inline assembly more than once. In either of these situations, your code will fail. (It is possible to patch inline assembly, but the requirements are very strict.)

onlyonemac wrote:
I also don't know what your pointer alignment issue is, all I'm doing is overwriting one value in memory with a different value, so if the original value is aligned then the replacement will be aligned too and if the original value isn't aligned then that's not my fault because the original value was produced by inline assembly which should be aligned correctly by the assembler.

The alignment requirements of C are separate from the alignment requirements of the CPU.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 29 posts ]  Go to page Previous  1, 2

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 79 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group