# Help with endless Code Generation step while creating GDT array for my zig OS kernel

**URL:** <https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117>\
**Category:** Help\
**Tags:** zig-0-13, packed-structs, cross-compile, operating-system, zig-master\
**Created:** [September 24, 2024, 1:08pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117 "2024-09-24T13:08:01Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![glitchcake](https://ziggit.dev/user_avatar/ziggit.dev/glitchcake/32/2361_2.png) [@glitchcake](https://ziggit.dev/u/glitchcake)\
**Post date:** [September 24, 2024, 1:08pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/1 "2024-09-24T13:08:01Z")

</div>

Hello,

I’m having an issue I haven’t come across before, namely that the Code Generation step seems to spin endlessly (longer than I expect it should take, it has run 5 or 10 minutes by now).

[My code](https://codeberg.org/glitchcake/zig-operating-system/src/branch/gc-2024-09-24-gdt)

Main builds and runs, but not gc-2024-09-24-gdt.

It seems to be specifically related to the presence of the `makeGdtEntry` call(s). It will compile and run if I take those calls out.

I am not sure what’s wrong here, any insight would be much appreciated `^_^`

**Zig Version 0.13.0**

```zig
> zigup run 0.13.0 build
[0/3] steps
└─ [2] zig build-exe kernel.elf Debug x86-frees
   ├─ [132] Semantic Analysis
   │ ├─ gdt.gdt_entries
   │ └─ gdt.init
   └─ [19] Code Generation

```

**Zig Version 0.14.0-dev.1637+8c232922b**

```zig
> zigup run master build
[0/3] steps
└─ [3] zig build-exe kernel.elf Debug x86-frees
   ├─ [137] Semantic Analysis
   │ ├─ gdt.gdt_entries
   │ └─ gdt.init
   └─ [2] Code Generation

```

**Relevant Code Samples (from src/gdt.zig)**

```zig
/// The GDT entry table containing NUMBER_OF_ENTRIES entries.
var gdt_entries: [NUMBER_OF_ENTRIES]GdtEntry = .{
    // Null descriptor
    makeGdtEntry(0, 0, NULL_SEGMENT, NULL_FLAGS),

    // Kernel code descriptor
    // makeGdtEntry(0, 0xFFFFF, KERNEL_SEGMENT_CODE, PAGING_32_BIT),

    // Kernel data descriptor
    // makeGdtEntry(0, 0xFFFFF, KERNEL_SEGMENT_DATA, PAGING_32_BIT),

    // User code descriptor
    // makeGdtEntry(0, 0xFFFFF, USER_SEGMENT_CODE, PAGING_32_BIT),

    // User data descriptor
    // makeGdtEntry(0, 0xFFFFF, USER_SEGMENT_DATA, PAGING_32_BIT),

    // TSS descriptor, one each for each processor.
    // Will initialize the TSS at runtime.
    // makeGdtEntry(0, 0, NULL_SEGMENT, NULL_FLAGS),
};

```

```zig
///
/// Make a GDT entry.
///
/// Arguments:
/// IN base: u32 - The linear address where the segment begins.
/// IN limit: u20 - The maximum addressable unit whether it is 1B units or page units.
/// IN access: AccessBits - The access bits for the descriptor.
/// IN flags: FlagBits - The flag bits for the descriptor.
///
/// Return: GdtEntry
/// A new GDT entry with the given access and flag bits set.
///
fn makeGdtEntry(base: u32, limit: u20, access: AccessBits, flags: FlagBits) GdtEntry {
    return .{
        .limit_low = @truncate(limit),
        .base_low = @truncate(base),
        .access = .{
            .accessed = access.accessed,
            .read_write = access.read_write,
            .direction_conforming = access.direction_conforming,
            .executable = access.executable,
            .descriptor = access.descriptor,
            .privilege = access.privilege,
            .present = access.present,
        },
        .limit_high = @truncate(limit >> 16),
        .flags = .{
            .reserved_zero = flags.reserved_zero,
            .is_64_bit = flags.is_64_bit,
            .is_32_bit = flags.is_32_bit,
            .granularity = flags.granularity,
        },
        .base_high = @truncate(base >> 24),
    };
}

```

```zig
pub fn init() void {
    console.printf("NUMBER_OF_ENTRIES: {}\n", .{NUMBER_OF_ENTRIES});
    console.printf("TABLE_SIZE: {}\n", .{TABLE_SIZE});
    console.printf("KERNEL_SEGMENT_CODE: {}\n", .{KERNEL_SEGMENT_CODE});
    console.printf("gdt_entries[0]: {}\n", .{gdt_entries[0]});
...
}

```

Using gdt\_entries[0] is enough to get the whole thing to start stalling, assuming there’s a `makeGdtEntry` call in there.

**Bonus Screenshot**

 ![image](https://ziggit.dev/uploads/default/original/2X/7/71c4c76b791c62fd45538e30cf84a27448078497.png)

---

<div class="post-metadata">

**Author:** ![LucasSantos91](https://ziggit.dev/user_avatar/ziggit.dev/lucassantos91/32/440_2.png) [@LucasSantos91](https://ziggit.dev/u/LucasSantos91)\
**Post date:** [September 24, 2024, 1:48pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/2 "2024-09-24T13:48:39Z")

</div>

It’s compiling fine for me. I’m using today’s Zig binary.  
Are you sure that it’s not just the UI bugging out? This has tripped me up a few times. Progress report sometimes forgets to clean up after it’s done, so it looks like it’s still going.

---

<div class="post-metadata">

**Author:** ![glitchcake](https://ziggit.dev/user_avatar/ziggit.dev/glitchcake/32/2361_2.png) [@glitchcake](https://ziggit.dev/u/glitchcake)\
**Post date:** [September 24, 2024, 1:51pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/3 "2024-09-24T13:51:08Z")

</div>

Oh wow, interesting! Thank you for trying on your machine! Let me investigate this…

I was also looking through issues, and thought that perhaps this looked similar, but I haven’t looked into it more than reading: [compiler Infinit loop when initializing an array using a block · Issue #21335 · ziglang/zig · GitHub](https://github.com/ziglang/zig/issues/21335)

---

<div class="post-metadata">

**Author:** ![glitchcake](https://ziggit.dev/user_avatar/ziggit.dev/glitchcake/32/2361_2.png) [@glitchcake](https://ziggit.dev/u/glitchcake)\
**Post date:** [September 24, 2024, 2:02pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/4 "2024-09-24T14:02:19Z")

</div>

I’m using the same version of zig and have confirmed that I do not get a `zig-out` directory. So it does not seems it’s merely a graphical bug.

If you try to compile the latest commit, c031d3d, does it complete and generate a zig-out directory for you? Perhaps you were accidentally on main instead of gc-2024-09-24-gdt?

---

<div class="post-metadata">

**Author:** ![glitchcake](https://ziggit.dev/user_avatar/ziggit.dev/glitchcake/32/2361_2.png) [@glitchcake](https://ziggit.dev/u/glitchcake)\
**Post date:** [September 24, 2024, 2:09pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/5 "2024-09-24T14:09:02Z")

</div>

it appears to be this open issue, as the example within mirrors my experience and setup:

> <https://github.com/ziglang/zig/issues/19730>
>
> \### Zig Version
> 
> 0.12.0-dev.3676+21a6a1b0f
> 
> \### Steps to Reproduce and Observed …Behavior
> 
> \`\`\`
> $ git clone https://github.com/pkmn/engine.git
> \<snip\>
> $ cd engine
> $ git reset --hard 047d6e71f60dbbf8e645e5de491076cc3cdf3ea9
> $ zig version
> 0.12.0-dev.3676+21a6a1b0f
> $ zig build -Dlog -Dchance -Dcalc test
> steps \[8/17\] zig test Debug native... Semantic Analysis \[3862\] ...
> \`\`\`
> 
> hangs indefinitely. also repros on 0.12 and the latest 0.13 nightly (0.13.0-dev.8+c352845e8)
> 
> \### Expected Behavior
> 
> works in 0.12.0-dev.3667+77abd3a96
> 
> \`\`\`
> $ zig version
> 0.12.0-dev.3667+77abd3a96
> $ zig build -Dlog -Dchance -Dcalc test
> \`\`\`
> 
> (no output because tests successfully pass)

---

<div class="post-metadata">

**Author:** ![glitchcake](https://ziggit.dev/user_avatar/ziggit.dev/glitchcake/32/2361_2.png) [@glitchcake](https://ziggit.dev/u/glitchcake)\
**Post date:** [September 24, 2024, 2:13pm UTC](https://ziggit.dev/t/help-with-endless-code-generation-step-while-creating-gdt-array-for-my-zig-os-kernel/6117/6 "2024-09-24T14:13:36Z")

</div>

As per [unnest durations to workaround ziglang/zig#19730 · pkmn/engine@fb6de10 · GitHub](https://github.com/pkmn/engine/commit/fb6de1036a4b0060ac07d54ab55aa22e16112a71), it is demonstrated that this bug can be worked-around by unnesting the packed struct initializations.

Here is a working `makeGdtEntry` function:

```zig
fn makeGdtEntry(base: u32, limit: u20, access: AccessBits, flags: FlagBits) GdtEntry {
    const access_copy: AccessBits = .{
        .accessed = access.accessed,
        .read_write = access.read_write,
        .direction_conforming = access.direction_conforming,
        .executable = access.executable,
        .descriptor = access.descriptor,
        .privilege = access.privilege,
        .present = access.present,
    };
    const flags_copy: FlagBits = .{
        .reserved_zero = flags.reserved_zero,
        .is_64_bit = flags.is_64_bit,
        .is_32_bit = flags.is_32_bit,
        .granularity = flags.granularity,
    };
    return .{
        .limit_low = @truncate(limit),
        .base_low = @truncate(base),
        .access = access_copy,
        .limit_high = @truncate(limit >> 16),
        .flags = flags_copy,
        .base_high = @truncate(base >> 24),
    };
}

```
