comptime {
const desc = Descriptor.init(getInterruptStub(0), 0x08, .interruptGate, .bits32, 0, true);
@compileLog(desc);
}
const Descriptor = packed struct(u64) {
offset0: u16, // 0-15 Offset 0-15 Gibt das Offset des ISR innerhalb des Segments an. Wenn der entsprechende Interrupt auftritt, wird eip auf diesen Wert gesetzt.
selector: u16, // 16-31 Selector Gibt den Selector des Codesegments an, in das beim Auftreten des Interrupts gewechselt werden soll. Im Allgemeinen ist dies das Kernel-Codesegment (Ring 0).
ist: u3 = 0, // 32-34 000 / IST Gibt im LM den Index in die IST an, ansonsten 0!
_0: u5 = 0, // 35-39 Reserviert Wird ignoriert
type: InterruptType, // 40-42 Typ Gibt die Art des Interrupts an
bits: InterruptBits, // 43 D Gibt an, ob es sich um ein 32bit- (1) oder um ein 16bit-Segment (0) handelt.
// Im LM: Für 64-Bit LDT 0, ansonsten 1
_1: u1 = 0, // 44 0
privilege: u2, // 45-46 DPL Gibt das Descriptor Privilege Level an, das man braucht um diesen Interrupt aufrufen zu dürfen.
enabled: bool, // 47 P Gibt an, ob dieser Eintrag benutzt wird.
offset1: u16, // 48-63 Offset 16-31
pub fn init(offset: ?*const fn () callconv(.Naked) void, selector: u16, _type: InterruptType, bits: InterruptBits, privilege: u2, enabled: bool) Descriptor {
const offset_val = @intFromPtr(offset);
return Descriptor{
.offset0 = @as(u16, @truncate(offset_val & 0xFFFF)),
.offset1 = @as(u16, @truncate((offset_val >> 16) & 0xFFFF)),
.selector = selector,
.type = _type,
.bits = bits,
.privilege = privilege,
.enabled = enabled,
};
}
};
fn getInterruptStub(comptime i: u32) *const fn () callconv(.Naked) void {
const Wrapper = struct {
fn stub_with_zero() callconv(.Naked) void {
asm volatile (
// this handler has no error code pushed by the cpu, so we have to
\\ pushl $0
\\ pushl %[nr]
\\ jmp common_isr_handler
:
: [nr] "n" (i),
);
}
fn stub_with_errorcode() callconv(.Naked) void {
asm volatile (
// error code was already pushed by cpu already
\\ pushl %[nr]
\\ jmp common_isr_handler
:
: [nr] "n" (i),
);
}
};
return switch (i) {
8, 10...14, 17 => &Wrapper.stub_with_errorcode,
else => &Wrapper.stub_with_zero,
};
}
const InterruptType = enum(u3) {
interruptGate = 0b110,
trapGate = 0b111,
taskGate = 0b101,
};
const InterruptBits = enum(u1) {
bits32 = 1,
bits16 = 0,
};
This code is interpreting the address returned by getInterruptStub() as 0, while it's not available yet. this should definitly create a compile error and not silently assume 0.
Zig Version
0.13.0
Steps to Reproduce and Observed Behavior
run with
zig test
:outputs the following code:
Expected Behavior
This code is interpreting the address returned by
getInterruptStub()
as 0, while it's not available yet. this should definitly create a compile error and not silently assume 0.