Installing a C function into the IDT

T

The Prisoner

Hey-

I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT. And what happens about passing arguments?

I'd like to have something like this:

void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");

Is there any reason for this not to work? How do I set up the
interrupts? Would I need root privelidges to do that?

Thanks!!
 
J

jacob navia

The said:
Hey-

I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT. And what happens about passing
arguments?

I'd like to have something like this:

void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");

Is there any reason for this not to work? How do I set up the
interrupts? Would I need root privelidges to do that?

Thanks!!

This would be interrupt based exception handling... a risky business.

It would be difficult to write it in C. Normally interrupt servicing
routines should return with a return from interrupt instruction, and not
just a return like a normal function does. You compiler would need
to support that...

Besides, interrupt routines should not destroy any registers, and the
registers it uses should have been saved...

Etc. There many problems with this approach.
 
T

The Prisoner

jacob said:
This would be interrupt based exception handling... a risky business.

Jacob,

Why would it be risky? I'm glad it's not completely crazy if it's a
known technique.

It would be good because if you have a project with many *.c files, you
could just access one global exception-handling function without having
to put a declaration for it in every single source file.
It would be difficult to write it in C. Normally interrupt servicing
routines should return with a return from interrupt instruction, and not
just a return like a normal function does. You compiler would need
to support that...
>
Besides, interrupt routines should not destroy any registers, and the
registers it uses should have been saved...

OK... so I guess you need a bit of inline assembler before the interrupt
call, where you push registers. Then just before the end of the C
handler function, you have some more inline assembler that pops the
registers back and returns from interrupt.

This is starting to sound like it could work.

How do you put the function's address into the IDT? I guess it may be
simpler to have a void function taking a void parameter so there's no
need to worry about passing arguments.
 
I

Ian Collins

The said:
Hey-

I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT. And what happens about passing
arguments?

I'd like to have something like this:

void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");

Is there any reason for this not to work? How do I set up the
interrupts? Would I need root privelidges to do that?
Interrupts and their handling are beyond standard C.

Where they are used, interrupts handlers (like signal handlers on a Unix
like system) generally have their own context, they are synchronous.
There is little a handler can do to influence the main line code unless
that code polls some shared state. In other words even if you could use
interrupts for exceptions, the code would still have to check to see if
one had fired. So you gain nothing.
 
E

Erik Trulsson

The Prisoner said:
Hey-

I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT. And what happens about passing arguments?

I'd like to have something like this:

void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");

Is there any reason for this not to work? How do I set up the
interrupts? Would I need root privelidges to do that?

Thanks!!

All of what you are talking about is *completely* system-specific
and extremly non-portable. Ask in some other group that caters to
the specific system you are using.
I have no idea which system that might be since I am not familiar with
anything called an IDT or any system having an 'interrupt slot 42'.

(I will however note that on most modern general-purpose systems, normal
programs are not allowed to access anything connected to interrupts directly,
so it seems unlikely that you can do whatever it is you are trying to do.)
 
J

Jens Thoms Toerring

The Prisoner said:
I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT.

This is completely system dependent (assuming a system has an
"IDT" at all and the operating system lets you get at something
that low level which many probably won't, even if you have root
or admistrator privileges). And what about a multi-tasking
system? Just think about the situation that you would get in
if each programs would mess around with the IDT. I guess the
only system this could somehow be made to work would be DOS.
If that's you're system you probably better ask in a group
that specializes on system specific programming under DOS.
And what happens about passing arguments?

You can't pass arguments to interrupt handler functions since
they don't get called in the traditional sense, there's no-
thing that could pass it arguments.
I'd like to have something like this:
void malloc_failure();
Say I install this as interrupt slot 42, then I can do:
if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");
Is there any reason for this not to work?

You may or may not get something to work on the architecture
and OS you're currently using (but since you don't tell it's
impossible to say) but if you want your program also to run
under a different OS or even on a machine with a different
architecture you will be in for a rather nasty surprise.

Moreover "__asm__" is no standard C function. C99 has "asm",
but if you use that you throw out all hopes of portability.

Moreover, you shouldn't cast the return value of malloc().
iIt just keeps the compiler form warning you if you forgot
to include <stdlib.h> and thus a prototype for malloc() is
missing, which can result in very "interesting" bugs. And
you also shouldn't assume that an int always has 4 bytes,
while that may be the case on your system it's nothing you
can rely on.

Why don't you look for something more portable? E.g. do a
search on "exceptions in c" and look up the longjmp() and
setjmp() functions. It's possible to simulate some kind of
exception handling in a (more or less) standard C confor-
ming way - at least a lot more portable then with using
interrupts.
Regards, Jens
 
K

Keith Thompson

Ian Collins said:
Interrupts and their handling are beyond standard C.

Where they are used, interrupts handlers (like signal handlers on a Unix
like system) generally have their own context, they are synchronous.
[...]

Did you mean to write "asynchonous"?
 
K

Keith Thompson

Moreover "__asm__" is no standard C function. C99 has "asm",
but if you use that you throw out all hopes of portability.
[...]

No, C doesn't have "asm". Annex J (which is not normative) mentions
it as a common extension (see C99 J.5.10), but any implementation in
which "asm" is a keyword is non-conforming.
 
T

The Prisoner

Jens said:
This is completely system dependent (assuming a system has an
"IDT" at all and the operating system lets you get at something
that low level which many probably won't, even if you have root
or admistrator privileges). And what about a multi-tasking
system? Just think about the situation that you would get in
if each programs would mess around with the IDT. I guess the
only system this could somehow be made to work would be DOS.
If that's you're system you probably better ask in a group
that specializes on system specific programming under DOS.

Jens,

Are you 100% sure about that? I understood that in Real Mode, the IVT is
used, while in Protected Mode the IDT is used. So it should be possible
to make use of the IDT under Windows or Linux.

What I don't know is how to write a function's address into the IDT...
You can't pass arguments to interrupt handler functions since
they don't get called in the traditional sense, there's no-
thing that could pass it arguments.

Understood. I think a void function(void) will be OK.
 
K

Keith Thompson

Keith Thompson said:
Ian Collins said:
Interrupts and their handling are beyond standard C.

Where they are used, interrupts handlers (like signal handlers on a Unix
like system) generally have their own context, they are synchronous.
[...]

Did you mean to write "asynchonous"?

Or perhaps "asynchronous"? *sigh*
 
I

Ian Collins

Keith said:
Keith Thompson said:
Ian Collins said:
Interrupts and their handling are beyond standard C.

Where they are used, interrupts handlers (like signal handlers on a Unix
like system) generally have their own context, they are synchronous.
[...]

Did you mean to write "asynchonous"?

Or perhaps "asynchronous"? *sigh*
Yes, that one!
 
I

Ian Collins

The said:
Are you 100% sure about that? I understood that in Real Mode, the IVT is
used, while in Protected Mode the IDT is used. So it should be possible
to make use of the IDT under Windows or Linux.
You are talking very specific x86 details here, Linux runs on many
processors.
What I don't know is how to write a function's address into the IDT...
Which is probably a good thing. Such detail is for the operating
environment to manage, unless you are working on a standalone system.
Understood. I think a void function(void) will be OK.

No, it would not. See earlier posts (I think form Jacob) concerning the
nature of an interrupt handler, it is not a regular function (on most
common CPS, there will be exceptions).
 
J

Jens Thoms Toerring

Are you 100% sure about that? I understood that in Real Mode, the IVT is
used, while in Protected Mode the IDT is used. So it should be possible
to make use of the IDT under Windows or Linux.

I don't know about Windows but I am rather sure that Linux won't
let you get at something that essential for the systems health
from a userland program (I would also guess that Windows will
also not let you do that unless the guys in Redmond completely
lost their minds;-). And, while we're talking about Linux, that
would only work (if it would be possible at all) when running
on a x86-like architecture (the IDT seems to be something rather
x86-specific). But Linux runs on lots of different architectures
which may use completely different methods for dealing with
interrupts. So if you want to write for "Linux" stick to standard
C (plus the system specific extensions from e.g. POSIX you can't
avoid) and don't try to throw assembler into the mix (unless you
have an extremely specialized project to do, but exception hand-
ling for failures of memory allocations don't sound like that).
What I don't know is how to write a function's address into the IDT...

Again, absolutely system specific. On an x86-kind of architecture
(in protected mode) I think you will have to read the IDTR regis-
ter (something you can't do with C, you will have to resort to
assembler and which other architectures rather likely don't have),
calculate where the slot for the function pointer is and write the
functions address there. If you really want to do something like
that you will have to get yourself the specifications for your
processor and figure it out from there.

But none of this has really anything to do with the language C,
the topic of this group. Several things needed can't be done in
C and those that can be done could also be done using some other
language...
Regards, Jens
 
B

Ben Bacarisse

The Prisoner said:
I was reading about interrupts, and I got to thinking it would be a
real neat thing to use interrupts for program-wide exception
handling.
void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
__asm__ ("int $0x42");

Aside from all the "not C", "system specific" answers, what is it that
your idea offers over simply calling the function:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
malloc_failure();

? As it stands it just looks like non-standard, system specific
function call.
 
O

Owen Jacobson

Hey-

I was reading about interrupts, and I got to thinking it would be a real
neat thing to use interrupts for program-wide exception handling. What I
haven't been able to find is a clear guide or example program for how to
install a C function into the IDT. And what happens about passing arguments?

I'd like to have something like this:

void malloc_failure();

Say I install this as interrupt slot 42, then I can do:

if(!(p=(int*)malloc(1000*4))) // array of 1000 ints
   __asm__ ("int $0x42");

I'm impressed that nobody else has mentioned that casting the result
of malloc is a good way to hide bugs and a bad way to use malloc yet.
Or on your odd choice of int sizes. These are fairly serious problems
with your code that you should understand and solve before trying
anything as tricky, hazardous, and arcane as writing your own ISRs.

The cast is dangerous because it hides a missing include; with the
missing include, the "implicit" declaration of malloc will have the
wrong signature. This can and will lead to crashes. See
http://c-faq.com/malloc/mallocnocast.html .

The correct size of an int is sizeof (int), not 4. Even better would
be

p = malloc (1000 * sizeof (*p));

as it will stay in synch if you change the type of 'p' (say, to long)
in the future.

-o
 
C

cr88192

The Prisoner said:
Jens,

Are you 100% sure about that? I understood that in Real Mode, the IVT is
used, while in Protected Mode the IDT is used. So it should be possible to
make use of the IDT under Windows or Linux.

What I don't know is how to write a function's address into the IDT...

I doubt there is any specific mechanism for this.
more so, this would be a horror.

first off, you would need to have an interface for this in the kernel (a set
of registerable interrupt handlers).

however, this will only really cover kernel space.
why? do you understand how premptive multitasking works?...

this (along with ring0/ring3 issues), makes a major problem for handling
interrupts in userspace.


in effect, the address space of the running process is regularly swapped
out.
so, a tiny fraction of the time, any such handlers would point into your
app's process, and the rest of the time, they will point to the same
address, in any of any number of possibly running processes.

so, in the kernel, you could handle the interrupt, but then would need some
way to transfer it to the right process. this would either require swapping
processes on interrupt, queuing messages for particular processes, ...

none of this is very good...


however, although usually system specific, more than a few interesting
things can be done via the 'signal' mechanism...
 
A

Antoninus Twink

I don't know about Windows but I am rather sure that Linux won't
let you get at something that essential for the systems health
from a userland program

Right - it's just not possible in user space. There's a good piece about
installing interrupt handlers in a Linux kernel module in Chapter 9 of
"Linux Device Drivers", which seems to be available online:
http://www.xml.com/ldd/chapter/book/ch09.html

Of course the OP's idea is completely crazy, for all the reasons people
have described, but it sounds like he's motivated by curiosity and
"learning by doing" rather than trying to use interrupt-based exception
handling in a serious program, and that's no bad thing. If he googles
around a bit, there are lots of people interested in userspace device
drivers, and particularly how to poll to see whether an interrupt has
occurred by having the kernel communicate that information to userspace
programs through the /proc filesystem.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top