Coder Social home page Coder Social logo

Linux ABI issue (passing structs by value) about odin HOT 19 CLOSED

 avatar commented on August 20, 2024
Linux ABI issue (passing structs by value)

from odin.

Comments (19)

baines avatar baines commented on August 20, 2024 2

Linux uses the SystemV ABI, there's a pdf for it here: https://people.freebsd.org/~obrien/amd64-elf-abi.pdf

In the Parameter Passing section it describes passing structs. It looks like if the struct >16 bytes it'll always be passed in memory (via a pointer), but otherwise can be put in registers based on the rules on page 16-17.

from odin.

gingerBill avatar gingerBill commented on August 20, 2024 1

System V AMD64 ABI is now correctly supported.

from odin.

 avatar commented on August 20, 2024

vec4 doesn't work too:

#include <stdio.h>

struct vec4 { float x, y, z, w; };

void CFunction(struct vec4 x) {
  printf("Received struct vec4: %f %f %f %f\n", x.x, x.y, x.z, x.w);
}
#foreign_system_library myfunc "myfunc";

vec4 :: struct #ordered { x, y, z, w: f32 }

CFunction :: proc(x: vec4) #foreign myfunc;

main :: proc() {
  x: vec4;
  x.x = 1;
  x.y = 2;
  x.z = 3;
  x.w = 4;
  CFunction(x);
}
Received struct vec4: 1.000000 0.000000 2.000000 0.000000

But vec8 all of a sudden works:

#include <stdio.h>

struct vec8 { float x0, y0, z0, w0,
                    x1, y1, z1, w1; };

void CFunction(struct vec8 x) {
  printf("Received struct vec8: %f %f %f %f %f %f %f %f\n", x.x0, x.y0, x.z0, x.w0,
                                                            x.x1, x.y1, x.z1, x.w1);
}
#foreign_system_library myfunc "myfunc";

vec8 :: struct #ordered { x0, y0, z0, w0,
                          x1, y1, z1, w1: f32 }

CFunction :: proc(x: vec8) #foreign myfunc;

main :: proc() {
  x: vec8;
  x.x0 = 1;
  x.y0 = 2;
  x.z0 = 3;
  x.w0 = 4;
  x.x1 = 5;
  x.y1 = 6;
  x.z1 = 7;
  x.w1 = 8;
  CFunction(x);
}
Received struct vec8: 1.000000 2.000000 3.000000 4.000000 5.000000 6.000000 7.000000 8.000000

from odin.

 avatar commented on August 20, 2024

vec7 works too...

from odin.

 avatar commented on August 20, 2024

vec6 works too...

from odin.

 avatar commented on August 20, 2024

And vec5 works too. So it means 4 32-bit values and lower cause an issue, maybe it triggers some optimization Odin not aware of somewhere...

from odin.

 avatar commented on August 20, 2024

x86 difference (compiled with -O0 -g flags):

diff --git a/incorrect.txt b/correct.txt
index f254b47..b4e9251 100644
--- a/incorrect.txt
+++ b/correct.txt
@@ -114,20 +114,19 @@ Disassembly of section .text:
 0000000000000620 <CFunction>:
 #include <stdio.h>
 
-struct vec4 { float x0, y0, z0, w0; };
+struct vec4 { float x0, y0, z0, w0; char a; };
 
 void CFunction(struct vec4 x) {
  push   rbp
  mov    rbp,rsp
  sub    rsp,0x
+ lea    rax,[rbp+0x]
  lea    rdi,[rip+0x]
- movlps QWORD PTR [rbp-0x],xmm0
- movlps QWORD PTR [rbp-0x],xmm1
   printf("Received struct vec4: %f %f %f %f\n", x.x0, x.y0, x.z0, x.w0);
- cvtss2sd xmm0,DWORD PTR [rbp-0x]
- cvtss2sd xmm1,DWORD PTR [rbp-0x]
- cvtss2sd xmm2,DWORD PTR [rbp-0x]
- cvtss2sd xmm3,DWORD PTR [rbp-0x]
+ cvtss2sd xmm0,DWORD PTR [rax]
+ cvtss2sd xmm1,DWORD PTR [rax+0x]
+ cvtss2sd xmm2,DWORD PTR [rax+0x]
+ cvtss2sd xmm3,DWORD PTR [rax+0x]
  mov    al,0x
  call   500 <printf@plt>
  mov    DWORD PTR [rbp-0x],eax

from odin.

ThisDevDane avatar ThisDevDane commented on August 20, 2024

Might be an ABI issue? I think Odin only obeys windows x64 ABI atm.

from odin.

 avatar commented on August 20, 2024

@ThisDrunkDane maybe! Can't test on Windows, don't know how to create a dll with cl, not a Windows programmer... :)

from odin.

 avatar commented on August 20, 2024

Compiling with cl.exe /D_USRDLL /D_WINDLL main.c /MT /link /DLL /OUT:myfunc.dll

#include <stdio.h>

struct vec3 { float x, y, z; };

__declspec(dllexport)
void CFunction(struct vec3 x) {
  printf("Received struct vec3: %f %f %f\n", x.x, x.y, x.z);
}

produces a dll, but when I try to run the odin file with odin.exe run main.odin

myfunc.dll : fatal error LNK1107: invalid or corrupt file: cannot read at 0x2C0

from odin.

 avatar commented on August 20, 2024
λ dumpbin.exe /exports myfunc.dll                              
Microsoft (R) COFF/PE Dumper Version 12.00.31101.0             
Copyright (C) Microsoft Corporation.  All rights reserved.     
                                                               
                                                               
Dump of file myfunc.dll                                        
                                                               
File Type: DLL                                                 
                                                               
  Section contains the following exports for myfunc.dll        
                                                               
    00000000 characteristics                                   
    5905EDB1 time date stamp Sun Apr 30 16:59:13 2017          
        0.00 version                                           
           1 ordinal base                                      
           1 number of functions                               
           1 number of names                                   
                                                               
    ordinal hint RVA      name                                 
                                                               
          1    0 00001000 CFunction                            
                                                               
  Summary                                                      
                                                               
        4000 .data                                             
        1000 .pdata                                            
        7000 .rdata                                            
        1000 .reloc                                            
        C000 .text                                             
                                                               

¯\_(ツ)_/¯

from odin.

 avatar commented on August 20, 2024

Duh, I should've link to .lib file, not .dll :) Yep, it all works fine on Windows:

Received struct vec3: 1.000000 2.000000 3.000000

from odin.

gingerBill avatar gingerBill commented on August 20, 2024

This is an ABI problem on Linux. I do not know what Linux's ABI is. On Windows, I'm using this rule https://github.com/gingerBill/Odin/blob/1430ca30a3a0677fb395d2c5c190e86f02ed2b06/src/check_expr.c#L1060.
I have yet to figure out what Linux is because I personally am not support Linux.

from odin.

gingerBill avatar gingerBill commented on August 20, 2024

Assuming how LLVM IR "works", I would assume if the size <= 16, it will be passed by value, else it is passed by pointer. Is this the case even if the size is not a multiple of 2 (like with windows)?

from odin.

baines avatar baines commented on August 20, 2024

I'm not certain, but the pdf makes it sound like it's not limited to powers of two.

from odin.

gingerBill avatar gingerBill commented on August 20, 2024

If so, I'll just try that and see if this fixes @procedural's problem.

from odin.

Kelimion avatar Kelimion commented on August 20, 2024

Slightly rewritten example because #ordered no longer appears to be supported:

package abitest;

foreign import myfunc "libmyfunc.so";
@(default_calling_convention="c")
foreign myfunc {
	CFunction :: proc(x: vec3) ---;
}
vec3 :: struct { x, y, z: f32 };

main :: proc() {
  x: vec3;
  x.x = 1;
  x.y = 2;
  x.z = 3;
  CFunction(x);
}

Still seems to be broken.

$ odin run main.odin 
Received struct vec3: 1.000000 0.000000 0.000000

from odin.

gingerBill avatar gingerBill commented on August 20, 2024

The calling convention was never properly supported on Linux and I will need to see if I can fix this. On Linux, that vec3 struct would be passed in two registers: "64-bit vector" and a single float.

from odin.

CaptainKraft avatar CaptainKraft commented on August 20, 2024

I came across this bug today as well while trying to use the odin-sdl2 library.

Edit: the bug popped up when trying to pass a Color struct which is 4 u8s.

from odin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.