Matching struct layouts.

Hi.

I've a situation where I need to build and execute a function on the
fly (with LLVM of course :-). The function will need to take a pointer
to a C struct, which is defined by the host. That is, the built
function will be something like:

void func(struct XYZ *p)
{
    /* need to access members of p here */
}

How will I educate LLVM IR about 'struct XYZ' so that the code inside
can access it's members properly? How can I be sure that the alignment
and padding of the members of the existing struct layout and the LLVM
struct layout matches?

In the worst case I can construct the function as taking individual
struct members as individual parameters, but that would be inelegant..

Thanks,
-Mahadevan.

I've a situation where I need to build and execute a function on the
fly (with LLVM of course :-). The function will need to take a pointer
to a C struct, which is defined by the host. That is, the built
function will be something like:

void func(struct XYZ *p)
{
    /* need to access members of p here */
}

How will I educate LLVM IR about 'struct XYZ' so that the code inside
can access it's members properly? How can I be sure that the alignment
and padding of the members of the existing struct layout and the LLVM
struct layout matches?

If this is an arbitrary struct, it can be quite tricky. Do you have
to worry about bitfields and variable sized fields (for example a
variable length array at the end)? What about unions?

Ciao,

D.

> If this is an arbitrary struct, it can be quite tricky. Do you have
> to worry about bitfields and variable sized fields (for example a
> variable length array at the end)? What about unions?

There are no bitfields, but it does have a variable length array at the end.
There are no unions.

You could use llvm-gcc to convert the struct to an LLVM type.
Otherwise, it wouldn't be too hard to convert the struct by
hand as long as it doesn't have any exotic types in it. A
VLA at the end (with element type T) is currently represented
by placing a field of type T at the end (i.e. just one element).

Ciao,

Duncan.

PS: Please reply to the list as well as to me - that way others can
comment too.

But can I assume that both gcc and LLVM will layout the structure
in the same way (member alignment, padding)?

Regards,
-Mahadevan.

"Mahadevan R" <mdevan.foobar@gmail.com> writes:

You could use llvm-gcc to convert the struct to an LLVM type.
Otherwise, it wouldn't be too hard to convert the struct by
hand as long as it doesn't have any exotic types in it. A
VLA at the end (with element type T) is currently represented
by placing a field of type T at the end (i.e. just one element).

But can I assume that both gcc and LLVM will layout the structure
in the same way (member alignment, padding)?

llvm-gcc and gcc follows the same platform C ABI. So the answer to your
question is "yes".

> But can I assume that both gcc and LLVM will layout the structure
> in the same way (member alignment, padding)?

llvm-gcc and gcc follows the same platform C ABI. So the answer to your
question is "yes".

That's not entirely true. For example it assumes the user is not
using attributes to create types with unusual alignments or sizes.
Most of the gcc -> llvm struct type conversion is straightforward
but don't forget that gcc already did C -> gcc type conversion
(which is also mostly straightforward). As long as you stay in
the land of simple types doing the obvious thing should be fine.

Ciao,

Duncan.

PS: Try using llvm-gcc -emit-llvm to see how llvm-gcc is converting
things, and to validate your implementation.

Duncan Sands <baldrick@free.fr> writes:

> But can I assume that both gcc and LLVM will layout the structure
> in the same way (member alignment, padding)?

llvm-gcc and gcc follows the same platform C ABI. So the answer to your
question is "yes".

That's not entirely true. For example it assumes the user is not
using attributes to create types with unusual alignments or sizes.

Using attributes means bypassing the platform C ABI and introducing a
compiler-specific ABI, right?

My point is that if your code does not depend on a specific compiler
extensions, llvm-gcc shouldn't behave different wrt data layout.

[snip]

On LLVM side, llvm-gcc is responsible to create LLVM IR with appropriate struct layout. llvm-gcc interprets GCC's struct layout while creating LLVM IR. GCC's struct layout at this point is target specific. So any difference between gcc and LLVM struct layout is a bug or oversight in interpreting GCC's struct layout. If there is a bug in GCC's struct layout then llvm-gcc will create bug-to-bug compatible struct layout :slight_smile: