Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread Jan Mercl
On Wed, Sep 9, 2020 at 8:17 PM Ian Lance Taylor  wrote:

> Exact alignment/offset compatibility with the C ABI is not a goal.
> Sorry.  (It's actually harder than one might think to maintain that
> kind of compatibility.  For example, on x86, the C ABI uses one
> alignment for double variables and a different alignment for double
> variables that appear as a field in a struct.  Unless, of course, you
> use the -malign-double option.  And more generally some platforms have
> multiple C ABIs, including x86 if you count the MCU psABI.)
>
> The Go structs in the syscall package that need to match C structs are
> carefully written to work correctly.
>
> You may find the cgo -godefs option to be helpful, as it provides Go
> structs that exactly match C structs, given a particular set of
> compiler options.

Thanks a lot for the clarification. Assuming that IIRC, cgo -godefs
acquire the alignment/offset info by invoking the C compiler, it's
unfortunately not a good option for a project that aims to avoid CGo
in the first place. But I now think there's a feasible solution to
this problem, having not as high a cost as I feared first when reading
your answer. I shall see tomorrow.

Thanks again.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-Vq1d2mFwmb4FVjuAdmCfa%3Du%2BoNBqEoGmY%2B_ba2j5WBWw%40mail.gmail.com.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread Ian Lance Taylor
On Wed, Sep 9, 2020 at 4:59 AM Jan Mercl <0xj...@gmail.com> wrote:
>
> If the intent is to have Go alignments/offsets of types compatible
> with the C ABI then I think it's safe to say this is a bug.
>
> And the existence of the syscall package, in some cases passing
> Go-defined structs to the kernel that must be binary compatible with
> their C definitions, IMO suggests that the intent is indeed there.

Exact alignment/offset compatibility with the C ABI is not a goal.
Sorry.  (It's actually harder than one might think to maintain that
kind of compatibility.  For example, on x86, the C ABI uses one
alignment for double variables and a different alignment for double
variables that appear as a field in a struct.  Unless, of course, you
use the -malign-double option.  And more generally some platforms have
multiple C ABIs, including x86 if you count the MCU psABI.)

The Go structs in the syscall package that need to match C structs are
carefully written to work correctly.

You may find the cgo -godefs option to be helpful, as it provides Go
structs that exactly match C structs, given a particular set of
compiler options.

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAOyqgcW%2ByA%2BzE4afZ81GJHCXm%3De9tfz-8gD99EQiEe%2Bk7xOKRw%40mail.gmail.com.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread Jan Mercl
On Wed, Sep 9, 2020 at 1:45 PM 'Dan Kortschak' via golang-nuts
 wrote:

> I think it comes down to these lines in src/cmd/internal/sys/arch.go
> [1]
>
> ```
> var ArchARM = {
> Name:  "arm",
> Family:ARM,
> ByteOrder: binary.LittleEndian,
> PtrSize:   4,
> RegSize:   4,
> MinLC: 4,
> }
>
> var ArchARM64 = {
> Name:  "arm64",
> Family:ARM64,
> ByteOrder: binary.LittleEndian,
> PtrSize:   8,
> RegSize:   8,
> MinLC: 4,
> }
> ```
> this line in src/cmd/compile/internal/gc/main.go [2]
> ```
> Widthreg = thearch.LinkArch.RegSize
> ```
>
> and these lines in src/cmd/compile/internal/gc/align.go [3]
> ```
> case TINT64, TUINT64, TFLOAT64:
> w = 8
> t.Align = uint8(Widthreg)
> ```
>
> [1]https://golang.org/src/cmd/internal/sys/arch.go
> [2]https://golang.org/src/cmd/compile/internal/gc/main.go
> [3]https://golang.org/src/cmd/compile/internal/gc/align.go

Thank you very much for the thorough investigation.

If the intent is to have Go alignments/offsets of types compatible
with the C ABI then I think it's safe to say this is a bug.

And the existence of the syscall package, in some cases passing
Go-defined structs to the kernel that must be binary compatible with
their C definitions, IMO suggests that the intent is indeed there.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-UFLsy0%3DSAWR3CM2YqVTWcEAgfQpkRaAn0LWkSQ%3DWeTcw%40mail.gmail.com.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread 'Dan Kortschak' via golang-nuts
On Wed, 2020-09-09 at 13:21 +0200, Jan Mercl wrote:
> 
> 
> On Wed, Sep 9, 2020 at 1:09 PM 'Dan Kortschak' via golang-nuts <
> golang-nuts@googlegroups.com> wrote:
> 
> > What does cgo -godefs give you? On my amd64 and arm64 I get this:
> >
> > ```
> > ~/cznic $ cat main.go
> > package main
> >
> > /*
> > struct s {
> > long long i;
> > } x;
> > */
> > import "C"
> >
> > type S struct {
> > i int64
> > }
> >
> > type C_s C.struct_s
> >
> > ~/cznic $ go tool cgo -godefs main.go
> > // Code generated by cmd/cgo -godefs; DO NOT EDIT.
> > // cgo -godefs main.go
> >
> > package main
> >
> > type S struct {
> > i int64
> > }
> >
> > type C_s struct {
> > I int64
> > }
> > ```
> 
> amd64
> =
> 
> 
> jnml@e5-1650:~/tmp$ go version
> go version go1.15.1 linux/amd64
> jnml@e5-1650:~/tmp$ cat main.go 
> package main
> 
> /*
> struct s {
> long long i;
> } x;
> */
> import "C"
> 
> type S struct {
> i int64
> }
> 
> type C_s C.struct_s
> jnml@e5-1650:~/tmp$ go tool cgo -godefs main.go
> // Code generated by cmd/cgo -godefs; DO NOT EDIT.
> // cgo -godefs main.go
> 
> package main
> 
> type S struct {
> i int64
> }
> 
> type C_s struct {
> I int64
> }
> jnml@e5-1650:~/tmp$ 
> 
> arm
> =
> ==
> 
> pi@raspberrypi:~/src/tmp.tmp $ go version
> go version go1.15.1 linux/arm
> pi@raspberrypi:~/src/tmp.tmp $ cat main.go
> package main
> 
> /*
> struct s {
> long long i;
> } x;
> */
> import "C"
> 
> type S struct {
> i int64
> }
> 
> type C_s C.struct_s
> pi@raspberrypi:~/src/tmp.tmp $ go tool cgo -godefs main.go
> // Code generated by cmd/cgo -godefs; DO NOT EDIT.
> // cgo -godefs main.go
> 
> package main
> 
> type S struct {
> i int64
> }
> 
> type C_s struct {
> I int64
> }
> pi@raspberrypi:~/src/tmp.tmp $ 
> 
> No difference between the outputs AFAICT. Seems good to me.
> 
> 

I think it comes down to these lines in src/cmd/internal/sys/arch.go
[1]

```
var ArchARM = {
Name:  "arm",
Family:ARM,
ByteOrder: binary.LittleEndian,
PtrSize:   4,
RegSize:   4,
MinLC: 4,
}

var ArchARM64 = {
Name:  "arm64",
Family:ARM64,
ByteOrder: binary.LittleEndian,
PtrSize:   8,
RegSize:   8,
MinLC: 4,
}
```
this line in src/cmd/compile/internal/gc/main.go [2]
```
Widthreg = thearch.LinkArch.RegSize
```

and these lines in src/cmd/compile/internal/gc/align.go [3]
```
case TINT64, TUINT64, TFLOAT64:
w = 8
t.Align = uint8(Widthreg)
```

[1]https://golang.org/src/cmd/internal/sys/arch.go
[2]https://golang.org/src/cmd/compile/internal/gc/main.go
[3]https://golang.org/src/cmd/compile/internal/gc/align.go


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/9faee5b3868886c3c7415ecc1c2469f2e008abe2.camel%40kortschak.io.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread Jan Mercl
On Wed, Sep 9, 2020 at 1:09 PM 'Dan Kortschak' via golang-nuts <
golang-nuts@googlegroups.com> wrote:

> What does cgo -godefs give you? On my amd64 and arm64 I get this:
>
> ```
> ~/cznic $ cat main.go
> package main
>
> /*
> struct s {
> long long i;
> } x;
> */
> import "C"
>
> type S struct {
> i int64
> }
>
> type C_s C.struct_s
>
> ~/cznic $ go tool cgo -godefs main.go
> // Code generated by cmd/cgo -godefs; DO NOT EDIT.
> // cgo -godefs main.go
>
> package main
>
> type S struct {
> i int64
> }
>
> type C_s struct {
> I int64
> }
> ```

amd64
=

jnml@e5-1650:~/tmp$ go version
go version go1.15.1 linux/amd64
jnml@e5-1650:~/tmp$ cat main.go
package main

/*
struct s {
long long i;
} x;
*/
import "C"

type S struct {
i int64
}

type C_s C.struct_s
jnml@e5-1650:~/tmp$ go tool cgo -godefs main.go
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs main.go

package main

type S struct {
i int64
}

type C_s struct {
I int64
}
jnml@e5-1650:~/tmp$

arm
===

pi@raspberrypi:~/src/tmp.tmp $ go version
go version go1.15.1 linux/arm
pi@raspberrypi:~/src/tmp.tmp $ cat main.go
package main

/*
struct s {
long long i;
} x;
*/
import "C"

type S struct {
i int64
}

type C_s C.struct_s
pi@raspberrypi:~/src/tmp.tmp $ go tool cgo -godefs main.go
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs main.go

package main

type S struct {
i int64
}

type C_s struct {
I int64
}
pi@raspberrypi:~/src/tmp.tmp $

No difference between the outputs AFAICT. Seems good to me.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-Xj22QAWdU-CjxibUhBEwxChm-HOORUUxbpfG2ihY0Sjg%40mail.gmail.com.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread 'Dan Kortschak' via golang-nuts
On Wed, 2020-09-09 at 12:50 +0200, Jan Mercl wrote:
> On Wed, Sep 9, 2020 at 12:41 PM Dan Kortschak 
> wrote:
> 
> > I get the following
> > 
> > ```
> >  C alignof struct s: 8
> > Go alignof struct s: 8
> > Go alignofS: 8
> > ~/cznic $ go version
> > go version go1.15.1 linux/arm64
> > ~/cznic $ uname -a
> > Linux bildr 4.19.0-10-arm64 #1 SMP Debian 4.19.132-1 (2020-07-24)
> > aarch64 GNU/Linux
> > ```
> > 
> > I have an arm64 linux running on my pi, maybe the armv7l behaviour
> > is
> > different.
> 
> Seems to be the case as armv7l is AFAIK a 32 bit only CPU. And arm64
> is next on the list of my targets so thank you for the information.
> 
> But the question is still the same. Is it a bug or is my assumption
> about Go and C agreeing on alignments/offsets invalid? I realizethe
> specs say nothing in this regard.

What does cgo -godefs give you? On my amd64 and arm64 I get this:

```
~/cznic $ cat main.go 
package main

/*
struct s {
long long i;
} x;
*/
import "C"

type S struct {
i int64
}

type C_s C.struct_s

~/cznic $ go tool cgo -godefs main.go 
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
// cgo -godefs main.go

package main

type S struct {
i int64
}

type C_s struct {
I int64
}
```


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/bf4ba2bfde7a4a0c2d858e5ae1af8c118694b541.camel%40kortschak.io.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread Jan Mercl
On Wed, Sep 9, 2020 at 12:41 PM Dan Kortschak  wrote:

> I get the following
>
> ```
>  C alignof struct s: 8
> Go alignof struct s: 8
> Go alignofS: 8
> ~/cznic $ go version
> go version go1.15.1 linux/arm64
> ~/cznic $ uname -a
> Linux bildr 4.19.0-10-arm64 #1 SMP Debian 4.19.132-1 (2020-07-24)
> aarch64 GNU/Linux
> ```
>
> I have an arm64 linux running on my pi, maybe the armv7l behaviour is
> different.

Seems to be the case as armv7l is AFAIK a 32 bit only CPU. And arm64
is next on the list of my targets so thank you for the information.

But the question is still the same. Is it a bug or is my assumption
about Go and C agreeing on alignments/offsets invalid? I realizethe
specs say nothing in this regard.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-XvvraqMF_5boDqFo%3DSVLdTo79bX-AJyAfQBJxVu1Tx4A%40mail.gmail.com.


Re: [go-nuts] linux/arm struct alignment seems wrong

2020-09-09 Thread 'Dan Kortschak' via golang-nuts
On Wed, 2020-09-09 at 12:19 +0200, Jan Mercl wrote:
> Observation:
> 
> pi@raspberrypi:~/src/tmp.tmp $ go version
> go version go1.15.1 linux/arm
> pi@raspberrypi:~/src/tmp.tmp $ cat main.go
> package main
> 
> /*
> 
> struct s {
> long long i;
> } x;
> 
> size_t align() {
> return _Alignof(struct s);
> }
> 
> */
> import "C"
> 
> import (
> "fmt"
> "unsafe"
> )
> 
> type S struct {
> i int64
> }
> 
> func main() {
> fmt.Printf(" C alignof struct s: %v\n", C.align())
> fmt.Printf("Go alignof struct s: %v\n",
> unsafe.Alignof(C.struct_s{}))
> fmt.Printf("Go alignofS: %v\n", unsafe.Alignof(S{}))
> }
> pi@raspberrypi:~/src/tmp.tmp $ go run main.go
>  C alignof struct s: 8
> Go alignof struct s: 4
> Go alignofS: 4
> pi@raspberrypi:~/src/tmp.tmp $ uname -a
> Linux raspberrypi 4.19.66-v7+ #1253 SMP Thu Aug 15 11:49:46 BST 2019
> armv7l GNU/Linux
> pi@raspberrypi:~/src/tmp.tmp $
> 
> My code relies on all the numbers being the same, ie. that Go will
> report the same as C for both C.struct_s{} and S{}.
> AFAICT Go and C agree on struct layout on linux/{amd64,386} perfectly
> in all cases I've tested (thousands probably).
> 
> Is this a bug or are my expectations ill founded?
> 
> Thanks in advance for any insights.
> 

I get the following

```
 C alignof struct s: 8
Go alignof struct s: 8
Go alignofS: 8
~/cznic $ go version
go version go1.15.1 linux/arm64
~/cznic $ uname -a
Linux bildr 4.19.0-10-arm64 #1 SMP Debian 4.19.132-1 (2020-07-24)
aarch64 GNU/Linux
```

I have an arm64 linux running on my pi, maybe the armv7l behaviour is
different.

Dan


-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/da8da3f14f311a23ab0191d7e8ba130a068c73b8.camel%40kortschak.io.