dissertation/Tech/sys/arch/amd64/amd64/genassym.md

2.8 KiB

genassym

While trying to build the OpenBSD kernel with tcc I stumbled upon a problem with genassym.sh(8). tcc does not have the option '-no-integrated-as' and does not know about the constraint 'n' present in the asm directives.

I'm not willing to add those flags in tcc so I think I found a better solution. ATM the flow looks something like this:

  • generate a .c file with all macro definitions that need to be compiled in order to have sense
  • generate the assembly file based on the .c file
  • do some text processing on the assembly file in order to generate a .h file with the needed macro definitions

Instead of this clumsy workflow let's try something like this:

  • write the macro definitions and their values directly to a .h file

That's it. It's portable, does not rely on specific compiler behaviour and it's cleaner. Speed is not a concern in this case.

However I realised something now. Each architecture has a genassym.cf file. How do I write a generic genassym.c that can be aware of the architecture?

Another problem is that I need to be aware of the type of the value of the macro definition? Does it matter that it is a string or an integer? I don't know that ATM, my guess is that it might matter.

For the first problem I found the following solution:

#define _stringify(x) #x
#define stringify_arch(x) _stringify(x)

#include stringify_arch(_MACHINE/include/trap.h)
#include stringify_arch(_MACHINE/include/pmap.h)
#include stringify_arch(_MACHINE/include/pte.h)
#include stringify_arch(_MACHINE/include/vmparam.h)
#include stringify_arch(_MACHINE/include/intr.h)
#include stringify_arch(_MACHINE/include/pic.h)
#include stringify_arch(_MACHINE/include/tss.h)
#include stringify_arch(_MACHINE/include/i82093var.h)

For the second problem, I print with %d if it's a numeric value and with %s if it is a string value. I just looked in the assym.h generated by the old script and realised that there are only numeric values. This problem disappears.

The first problem (that one with includes) is overengineered. release(8) describes the process of building the kernel, in this process the make rules create a machine directory where they place all the machine-dependent header files. So the above statements can be converted in something like this:

#include <machine/trap.h>

As simple as that.

Some days latter, I moved genassym from usr.bin/ to sys/ because it makes more sense to be compiled there (genassym.cf is also present is sys/). I successfully integrated in with the Makefiles and it generates correct output for the marco-definitions.

One strange thing that I noticed is that there are multiple genassym.cf files in sys/arch/amd64/ and I don't know if I need to integrated all of them in my C version. For the moment I will let the other .cf files be and if I catch a missing definition that is present in those files I will review them.