
Thursday September 06, 2007
How do you access structure members in assembly files...
How do you access structure members in assembly files...
If you look at the assembly files in OpenSolaris kernel [fortunately
there are not many of them], you will see instructions like the one
below at quite a few places :
movq T_PROCP(%r13), %r14 /*
%r14 = proc */ <-- from
swtch.s
In this particular case, %r13 holds the thread pointer and it is
accessing the proc pointer from it and storing it in %r14. How it is
accessing the member is the focus of this post.
If this was a c-source file, we could have done something similar to:
proc_t *p = t->t_procp;
and compiler will take care of the rest.
But if we need to code it in assembly, we have to explicitly pass the
'offset' of the member [here, t_procp] to the instrcution. But if we
were to hard code the 'offset', it would be a nightmare to maintain it,
whenever structures changed.
So how OpenSolaris addresses this is pretty neat.
There is a file called
offsets.in,
which has entries as shown below :
_kthread
THREAD_SIZE
t_pcb
T_LABEL
t_lock
.....
t_procp
t_link
This file gets compiled into a header file called assym.h and it can be
included in any assembly file that makes references to these members.
This
Makefile
takes care of building the header file. Looking at the assym.h, after
building it, the entry for t_procp looks like this :
#define T_PROCP 0xdc
This is exactly what we need to feed to the assembly instruction !!
If we need to access a structure member that is not already present in
the
offsets.in,
all we need to do is, just add the 'appropriate structure and its
member', compile and start accessing in the assembly code.
What if the structure I am interested in is not of global signifcance -
i.e no other module other than mine may care about it - in which case I
don't want to clutter the
offsets.in
but want my own offsets.in which does the same job.
An example for this can be found here
offsets.in
- the structure and offsets that are declared here are of no
significance to sparc so just confine it to x86.
You can use make(1S)'s AS_INC_PATH env varaible in your Makefiles to
point to the location of where the generated heder files are present -
with this varaible, you don't end up including the header file path for
your c-files [confine it to assembly files].
( Sep 06 2007, 09:46:06 PM PDT )
Permalink