Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to re-use C structs in ARM assembly in a maintainable and readable way?

When accessing struct fields, I've been manually adding offsets to addresses to get access to the fields. This is pretty tedious, hard to read and a maintenance headache.

Is there a nicer way to access C struct fields?

For example, I'm thinking of a syntax like this:

example.h: typedef struct { int a; int b; } MyStruct;

example.s: ldr r1, [r2, #MyStruct.b] // r2 contains an address to a MyStruct

like image 215
Martijn Thé Avatar asked Mar 05 '14 00:03

Martijn Thé


2 Answers

There is really no clean and portable way. Most projects I've seen that do have some build step that generates a header file of struct offsets. It goes a little something like this:

1) Create a C file that defines your offsets

#include "mystruct.h"

#define DECLARE(SYM,VAL) \
__asm("__AS_DEFINE__ " SYM "\t%0" : : "n" ((unsigned long)(VAL)))

void foo(void)
{
    // mystruct.h
    DECLARE("MYSTRUCT_B",  offsetof(struct mystruct, b));
}

2) Compile that file with the flag to generate assembly (-S on Clang or GCC). This will create an assembly file with a bunch of defined lines such as:

    __AS_DEFINE__ MYSTRUCT_B    #4

3) Use some shell tricks to turn these into a header file for your assembly code.

grep '__AS_DEFINE__' offsets.s | sed 's/#//g' | sed 's/__AS_DEFINE__/#define/g' > build/include/offsets.h

Which yields a file that looks like this and can be included in your assembly sources.

    #define MYSTRUCT_B  4

You can then use this directly.

#include "offsets.h"

    ldr r1, [r2, #MYSTRUCT_B]
like image 172
Variable Length Coder Avatar answered Oct 10 '22 23:10

Variable Length Coder


asm(
        "ldr r0, [r1, %[my_offset]] \n" : : [my_offset]"i" (offsetof(MyStruct, a))
    );
like image 1
Anton Plakhotnyk Avatar answered Oct 10 '22 22:10

Anton Plakhotnyk