~mcf

https://mforney.org

Trackers

~mcf/cproc

Last active a month ago

~mcf/x509cert

Last active 5 months ago

~mcf/dnssec-rr

Last active 1 year, 5 months ago

~mcf/libtls-bearssl

Last active 1 year, 10 months ago

~mcf/qbe

Last active 2 years ago

~mcf/oasis

Last active 2 years ago

~mcf/sbase

Last active 2 years ago

~mcf/samurai

Last active 2 years ago

#62 Build musl libc a month ago

Comment by ~mcf on ~mcf/cproc

It only uses -fPIC when it detects that the compiler enables it by default. Since cproc is using gcc as a preprocessor, if gcc is built with --enable-default-pie it defines __PIC__ by default, which is not correct since qbe doesn't generate position-independent code.

I pushed a couple of commits to fix this. Now, you should be able to do CC=cproc ./configure --target=x86_64-linux-musl && make -k lib/libc.a to see all the errors.

There are only a handful of unique errors, but these are all major features that need support from QBE (apart from _Complex maybe):

$ make -k lib/libc.a 2>&1 | grep -e error: -e cproc-qbe: | sort -u
./arch/x86_64/atomic_arch.h:3:2: error: inline assembly is not yet supported
./arch/x86_64/syscall_arch.h:6:2: error: inline assembly is not yet supported
./include/complex.h:16:8: error: _Complex is not yet supported
cproc-qbe: long double is not yet supported
src/network/if_nameindex.c:95:52: error: VLAs are not yet supported
src/process/execl.c:12:20: error: VLAs are not yet supported
src/process/execle.c:12:20: error: VLAs are not yet supported
src/process/execlp.c:12:20: error: VLAs are not yet supported
src/process/execvp.c:29:15: error: VLAs are not yet supported
src/search/lsearch.c:6:17: error: VLAs are not yet supported
src/string/explicit_bzero.c:6:2: error: inline assembly is not yet supported
$

#75 Explicit Types Confuse Initializer a month ago

Comment by ~mcf on ~mcf/cproc

Thanks for the clear report and test case.

This syntax is perfectly fine for initializing local variables inside a function, but not for static or global variables. The C standard describes this restriction in 6.7.9p4:

All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.

What you have here on the right hand side is a compound literal expression, which is not a constant expression or string literal. A constant expression must be one of the following (6.6p7):

  • an arithmetic constant expression,
  • a null pointer constant,
  • an address constant, or
  • an address constant for a complete object type plus or minus an integer constant expression.

I believe the reason why this works in gcc and clang is because of 6.7p10:

An implementation may accept other forms of constant expressions.

But this is not something you can rely upon in your code. And indeed, if you enable -Wpedantic, gcc will warn about this:

test.c:2:20: warning: initializer element is not constant [-Wpedantic]
    2 | struct dummy str = (struct dummy){.label = "Redraw"};

The reason that struct dummy str = {.label = "Redraw"}; works is because there is only one expression in the initializer, the string literal "Redraw", which is explicitly allowed in initializers of global and static variables.

I got in the habit of doing this back when initializer "type inference" was worse and noticed it while trying to compile a program of mine.

I'm not sure what you mean by this. C doesn't have any initializer type inference; you always have to specify the types of the objects you initialize.

#66 Handle #line directives a month ago

on ~mcf/cproc

REPORTED RESOLVED FIXED

#74 Segfaults on invalid syntax 2 months ago

Comment by ~mcf on ~mcf/cproc

Thanks for the report. The problem was that declarator() was allowing an abstract function declarator (struct x(), i.e. function with unspecified arguments returning struct x), even when allowabstract was false.

Fixed by 87553780.

REPORTED RESOLVED FIXED

#73 Incomplete enum is not caught in struct field 3 months ago

Comment by ~mcf on ~mcf/cproc

Thanks for the report. This is fixed in eb4320fc.

I also added a few other checks to make sure that structs have at least one member and the flexible array member (if present) is last.

REPORTED RESOLVED FIXED

#6 Implement the preprocessor 3 months ago

Comment by ~mcf on ~mcf/cproc

Seems like an interesting project, but pp-1 is not a C preprocessor. Rather, it looks to be some sort of document templating program.

#65 Preprocess assembly inputs with `.S` extension 6 months ago

Comment by ~mcf on ~mcf/cproc

This was fixed in 28146f5e.

REPORTED RESOLVED FIXED

#44 gmnisrv: pollfd realloc or client disconnection invalidates past pollfd pointers 11 months ago

Comment by ~mcf on ~sircmpwn/gmni

Yes, I think that should work. You could also go further and keep a parallel array containing a linked list of free pollfd indices. When a client exits, just update its index in the free list with the previous head, and when you accept a new client, check if there are any free pollfds before reallocating the array. I'm not sure if the extra complexity is worth it over just scanning the array for a free index, though.

#18 Switch to some other TLS implementation 11 months ago

Comment by ~mcf on ~sircmpwn/gmni

I'm not sure if it meets your criteria, but I'd be interested in porting gmnisrv to bearssl.

#44 gmnisrv: pollfd realloc or client disconnection invalidates past pollfd pointers 11 months ago

Ticket created by ~mcf on ~sircmpwn/gmni

I noticed that if gmniserve ever has to realloc the fds array because it had over 1024 simultaneous clients, then all the pollfd pointers saved in client structs become invalid.

Additionally, if two clients (1 and 2) are being served simultaneously and then client 1 disconnects first, then client 2's pollfd is shifted earlier in the array, but its pollfd pointer is not updated.

The first issue can be solved by keeping track of array indices instead of pointers. To solve the second issue, upon client disconnection you could loop through all subsequent clients and adjust their pollfd index.