mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-20 05:50:50 -05:00
build(deps): bump github.com/testcontainers/testcontainers-go
Bumps [github.com/testcontainers/testcontainers-go](https://github.com/testcontainers/testcontainers-go) from 0.40.0 to 0.41.0. - [Release notes](https://github.com/testcontainers/testcontainers-go/releases) - [Commits](https://github.com/testcontainers/testcontainers-go/compare/v0.40.0...v0.41.0) --- updated-dependencies: - dependency-name: github.com/testcontainers/testcontainers-go dependency-version: 0.41.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
committed by
Ralf Haferkamp
parent
fef601f104
commit
de59bb63ad
20
go.mod
20
go.mod
@@ -83,7 +83,7 @@ require (
|
||||
github.com/spf13/viper v1.21.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/test-go/testify v1.1.4
|
||||
github.com/testcontainers/testcontainers-go v0.40.0
|
||||
github.com/testcontainers/testcontainers-go v0.41.0
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.40.0
|
||||
github.com/theckman/yacspin v0.13.12
|
||||
github.com/thejerf/suture/v4 v4.0.6
|
||||
@@ -123,7 +123,7 @@ require (
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect
|
||||
filippo.io/edwards25519 v1.1.1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
|
||||
github.com/BurntSushi/toml v1.6.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
@@ -191,11 +191,11 @@ require (
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/docker/docker v28.5.1+incompatible // indirect
|
||||
github.com/docker/docker v28.5.2+incompatible // indirect
|
||||
github.com/docker/go-connections v0.6.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/ebitengine/purego v0.8.4 // indirect
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/emvi/iso-639-1 v1.1.1 // indirect
|
||||
@@ -295,12 +295,12 @@ require (
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/go-archive v0.2.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
@@ -325,7 +325,7 @@ require (
|
||||
github.com/pierrec/lz4/v4 v4.1.15 // indirect
|
||||
github.com/pjbgf/sha1cd v0.3.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/pquerna/cachecontrol v0.2.0 // indirect
|
||||
github.com/prometheus/alertmanager v0.31.1 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
@@ -349,7 +349,7 @@ require (
|
||||
github.com/sethvargo/go-diceware v0.5.0 // indirect
|
||||
github.com/sethvargo/go-password v0.3.1 // indirect
|
||||
github.com/shamaton/msgpack/v2 v2.4.0 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.6 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.26.2 // indirect
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
|
||||
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
|
||||
github.com/skeema/knownhosts v1.3.1 // indirect
|
||||
@@ -363,8 +363,8 @@ require (
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tinylib/msgp v1.6.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.14 // indirect
|
||||
github.com/tklauser/numcpus v0.8.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
|
||||
github.com/trustelem/zxcvbn v1.0.1 // indirect
|
||||
github.com/urfave/cli/v2 v2.27.7 // indirect
|
||||
|
||||
44
go.sum
44
go.sum
@@ -46,8 +46,8 @@ github.com/Acconut/go-httptest-recorder v1.0.0/go.mod h1:CwQyhTH1kq/gLyWiRieo7c0
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/Azure/azure-sdk-for-go v32.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest/autorest v0.1.0/go.mod h1:AKyIcETwSUFxIcs/Wnq/C+kwCtlEYGUVd7FPNb2slmg=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.1.0/go.mod h1:MeS4XhScH55IST095THyTxElntu7WqB7pNbZo8Q5G3E=
|
||||
@@ -310,8 +310,8 @@ github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E
|
||||
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
|
||||
github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM=
|
||||
github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
|
||||
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
|
||||
@@ -323,8 +323,8 @@ github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e/go.mod h1:Byz
|
||||
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
|
||||
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
|
||||
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
|
||||
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
|
||||
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
|
||||
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
|
||||
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc h1:6IxmRbXV8WXVkcYcTzkU219A3UZeNMX/e6X2sve1wXA=
|
||||
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc/go.mod h1:FdVN2WHg7zOHhJ7kZQdDorfFhIfqZaHttjAzDDvAXHE=
|
||||
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
|
||||
@@ -878,8 +878,8 @@ github.com/mna/pigeon v1.3.0 h1:/3fzVrl1C2RK3x04tyL+ribn+3S3VSEFFbCFLmRPAoc=
|
||||
github.com/mna/pigeon v1.3.0/go.mod h1:SKQNHonx2q9U2QSSoPtMigExj+vQ1mOpL7UVFQF/IA0=
|
||||
github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0=
|
||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||
github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ=
|
||||
github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo=
|
||||
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
|
||||
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
|
||||
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
|
||||
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
|
||||
github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw=
|
||||
@@ -890,8 +890,8 @@ github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
|
||||
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
|
||||
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
|
||||
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
|
||||
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -1013,8 +1013,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw=
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
|
||||
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
|
||||
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
|
||||
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
|
||||
@@ -1125,8 +1125,8 @@ github.com/shamaton/msgpack/v2 v2.4.0 h1:O5Z08MRmbo0lA9o2xnQ4TXx6teJbPqEurqcCOQ8
|
||||
github.com/shamaton/msgpack/v2 v2.4.0/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=
|
||||
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
|
||||
github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI=
|
||||
github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
|
||||
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
@@ -1202,8 +1202,8 @@ github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhg
|
||||
github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
|
||||
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
|
||||
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
|
||||
github.com/testcontainers/testcontainers-go v0.40.0 h1:pSdJYLOVgLE8YdUY2FHQ1Fxu+aMnb6JfVz1mxk7OeMU=
|
||||
github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY=
|
||||
github.com/testcontainers/testcontainers-go v0.41.0 h1:mfpsD0D36YgkxGj2LrIyxuwQ9i2wCKAD+ESsYM1wais=
|
||||
github.com/testcontainers/testcontainers-go v0.41.0/go.mod h1:pdFrEIfaPl24zmBjerWTTYaY0M6UHsqA1YSvsoU40MI=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.40.0 h1:3TIrGk0zXyO9CG2N6APo7auwWIwAvhkwE1reISif8LM=
|
||||
github.com/testcontainers/testcontainers-go/modules/opensearch v0.40.0/go.mod h1:VA0UCTPu+Gcs7MzdzBnSl0qDnxquuphv3ngSGdX97Xs=
|
||||
github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o=
|
||||
@@ -1224,10 +1224,10 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY=
|
||||
github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
|
||||
github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU=
|
||||
github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY=
|
||||
github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY=
|
||||
github.com/tklauser/numcpus v0.8.0/go.mod h1:ZJZlAY+dmR4eut8epnzf0u/VwodKmryxR8txiloSqBE=
|
||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
||||
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
||||
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM=
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||
@@ -1319,8 +1319,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0 h1:mq/Qcf28TWz719lE3/hMB4KkyDuLJIvgJnFGcd0kEUI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.41.0/go.mod h1:yk5LXEYhsL2htyDNJbEq7fWzNEigeEdV5xBF/Y+kAv0=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0 h1:wVZXIWjQSeSmMoxF74LzAnpVQOAFDo3pPji9Y4SOFKc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.40.0/go.mod h1:khvBS2IggMFNwZK/6lEeHg/W57h/IX6J4URh57fuI40=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0 h1:s/1iRkCKDfhlh1JF26knRneorus8aOwVIDhvYx9WoDw=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.42.0/go.mod h1:UI3wi0FXg1Pofb8ZBiBLhtMzgoTm1TYkMvn71fAqDzs=
|
||||
go.opentelemetry.io/otel/metric v1.42.0 h1:2jXG+3oZLNXEPfNmnpxKDeZsFI5o4J+nz6xUlaFdF/4=
|
||||
|
||||
41
vendor/github.com/Azure/go-ansiterm/SECURITY.md
generated
vendored
Normal file
41
vendor/github.com/Azure/go-ansiterm/SECURITY.md
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.8 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
||||
18
vendor/github.com/Azure/go-ansiterm/osc_string_state.go
generated
vendored
18
vendor/github.com/Azure/go-ansiterm/osc_string_state.go
generated
vendored
@@ -11,21 +11,13 @@ func (oscState oscStringState) Handle(b byte) (s state, e error) {
|
||||
return nextState, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case isOscStringTerminator(b):
|
||||
// There are several control characters and sequences which can
|
||||
// terminate an OSC string. Most of them are handled by the baseState
|
||||
// handler. The ANSI_BEL character is a special case which behaves as a
|
||||
// terminator only for an OSC string.
|
||||
if b == ANSI_BEL {
|
||||
return oscState.parser.ground, nil
|
||||
}
|
||||
|
||||
return oscState, nil
|
||||
}
|
||||
|
||||
// See below for OSC string terminators for linux
|
||||
// http://man7.org/linux/man-pages/man4/console_codes.4.html
|
||||
func isOscStringTerminator(b byte) bool {
|
||||
|
||||
if b == ANSI_BEL || b == 0x5C {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
8
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
8
vendor/github.com/docker/docker/api/swagger.yaml
generated
vendored
@@ -2653,14 +2653,6 @@ definitions:
|
||||
description: |
|
||||
Unique ID of the build cache record.
|
||||
example: "ndlpt0hhvkqcdfkputsk4cq9c"
|
||||
Parent:
|
||||
description: |
|
||||
ID of the parent build cache record.
|
||||
|
||||
> **Deprecated**: This field is deprecated, and omitted if empty.
|
||||
type: "string"
|
||||
x-nullable: true
|
||||
example: ""
|
||||
Parents:
|
||||
description: |
|
||||
List of parent build cache record IDs.
|
||||
|
||||
36
vendor/github.com/ebitengine/purego/README.md
generated
vendored
36
vendor/github.com/ebitengine/purego/README.md
generated
vendored
@@ -26,17 +26,36 @@ except for float arguments and return values.
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
- **FreeBSD**: amd64, arm64
|
||||
- **Linux**: amd64, arm64
|
||||
- **macOS / iOS**: amd64, arm64
|
||||
- **Windows**: 386*, amd64, arm*, arm64
|
||||
### Tier 1
|
||||
|
||||
`*` These architectures only support SyscallN and NewCallback
|
||||
Tier 1 platforms are the primary targets officially supported by PureGo. When a new version of PureGo is released, any critical bugs found on Tier 1 platforms are treated as release blockers. The release will be postponed until such issues are resolved.
|
||||
|
||||
- **Android**: amd64<sup>1</sup>, arm64<sup>1</sup>
|
||||
- **iOS**: amd64<sup>1</sup>, arm64<sup>1</sup>
|
||||
- **Linux**: amd64, arm64
|
||||
- **macOS**: amd64, arm64
|
||||
- **Windows**: amd64, arm64
|
||||
|
||||
### Tier 2
|
||||
|
||||
Tier 2 platforms are supported by PureGo on a best-effort basis. Critical bugs on Tier 2 platforms do not block new PureGo releases. However, fixes contributed by external contributors are very welcome and encouraged.
|
||||
|
||||
- **Android**: 386<sup>1</sup>, arm<sup>1</sup>
|
||||
- **FreeBSD**: amd64<sup>2</sup>, arm64<sup>2</sup>
|
||||
- **Linux**: 386, arm, loong64, ppc64le, riscv64, s390x<sup>1</sup>
|
||||
- **Windows**: 386<sup>3</sup>, arm<sup>3,4</sup>
|
||||
|
||||
#### Support Notes
|
||||
|
||||
1. These architectures require CGO_ENABLED=1 to compile
|
||||
2. These architectures require the special flag `-gcflags="github.com/ebitengine/purego/internal/fakecgo=-std"` to compile with CGO_ENABLED=0
|
||||
3. These architectures only support `SyscallN` and `NewCallback`
|
||||
4. These architectures are no longer supported as of Go 1.26
|
||||
|
||||
## Example
|
||||
|
||||
The example below only showcases purego use for macOS and Linux. The other platforms require special handling which can
|
||||
be seen in the complete example at [examples/libc](https://github.com/ebitengine/purego/tree/main/examples/libc) which supports Windows and FreeBSD.
|
||||
be seen in the complete example at [examples/libc](https://github.com/ebitengine/purego/tree/main/examples/libc) which supports FreeBSD and Windows.
|
||||
|
||||
```go
|
||||
package main
|
||||
@@ -84,14 +103,17 @@ License that can be found [in the Go Source](https://github.com/golang/go/blob/m
|
||||
This is a list of the copied files:
|
||||
|
||||
* `abi_*.h` from package `runtime/cgo`
|
||||
* `wincallback.go` from package `runtime`
|
||||
* `zcallback_darwin_*.s` from package `runtime`
|
||||
* `internal/fakecgo/abi_*.h` from package `runtime/cgo`
|
||||
* `internal/fakecgo/asm_GOARCH.s` from package `runtime/cgo`
|
||||
* `internal/fakecgo/callbacks.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/go_GOOS_GOARCH.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/iscgo.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/setenv.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/freebsd.go` from package `runtime/cgo`
|
||||
* `internal/fakecgo/netbsd.go` from package `runtime/cgo`
|
||||
|
||||
The `internal/fakecgo/go_GOOS.go` files were modified from `runtime/cgo/gcc_GOOS_GOARCH.go`.
|
||||
|
||||
The files `abi_*.h` and `internal/fakecgo/abi_*.h` are the same because Bazel does not support cross-package use of
|
||||
`#include` so we need each one once per package. (cf. [issue](https://github.com/bazelbuild/rules_go/issues/3636))
|
||||
|
||||
60
vendor/github.com/ebitengine/purego/abi_loong64.h
generated
vendored
Normal file
60
vendor/github.com/ebitengine/purego/abi_loong64.h
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R22_TO_R31(offset) saves R22 ~ R31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+9*8)(R3).
|
||||
//
|
||||
// SAVE_F24_TO_F31(offset) saves F24 ~ F31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+7*8)(R3).
|
||||
//
|
||||
// Note: g is R22
|
||||
|
||||
#define SAVE_R22_TO_R31(offset) \
|
||||
MOVV g, ((offset)+(0*8))(R3) \
|
||||
MOVV R23, ((offset)+(1*8))(R3) \
|
||||
MOVV R24, ((offset)+(2*8))(R3) \
|
||||
MOVV R25, ((offset)+(3*8))(R3) \
|
||||
MOVV R26, ((offset)+(4*8))(R3) \
|
||||
MOVV R27, ((offset)+(5*8))(R3) \
|
||||
MOVV R28, ((offset)+(6*8))(R3) \
|
||||
MOVV R29, ((offset)+(7*8))(R3) \
|
||||
MOVV R30, ((offset)+(8*8))(R3) \
|
||||
MOVV R31, ((offset)+(9*8))(R3)
|
||||
|
||||
#define SAVE_F24_TO_F31(offset) \
|
||||
MOVD F24, ((offset)+(0*8))(R3) \
|
||||
MOVD F25, ((offset)+(1*8))(R3) \
|
||||
MOVD F26, ((offset)+(2*8))(R3) \
|
||||
MOVD F27, ((offset)+(3*8))(R3) \
|
||||
MOVD F28, ((offset)+(4*8))(R3) \
|
||||
MOVD F29, ((offset)+(5*8))(R3) \
|
||||
MOVD F30, ((offset)+(6*8))(R3) \
|
||||
MOVD F31, ((offset)+(7*8))(R3)
|
||||
|
||||
#define RESTORE_R22_TO_R31(offset) \
|
||||
MOVV ((offset)+(0*8))(R3), g \
|
||||
MOVV ((offset)+(1*8))(R3), R23 \
|
||||
MOVV ((offset)+(2*8))(R3), R24 \
|
||||
MOVV ((offset)+(3*8))(R3), R25 \
|
||||
MOVV ((offset)+(4*8))(R3), R26 \
|
||||
MOVV ((offset)+(5*8))(R3), R27 \
|
||||
MOVV ((offset)+(6*8))(R3), R28 \
|
||||
MOVV ((offset)+(7*8))(R3), R29 \
|
||||
MOVV ((offset)+(8*8))(R3), R30 \
|
||||
MOVV ((offset)+(9*8))(R3), R31
|
||||
|
||||
#define RESTORE_F24_TO_F31(offset) \
|
||||
MOVD ((offset)+(0*8))(R3), F24 \
|
||||
MOVD ((offset)+(1*8))(R3), F25 \
|
||||
MOVD ((offset)+(2*8))(R3), F26 \
|
||||
MOVD ((offset)+(3*8))(R3), F27 \
|
||||
MOVD ((offset)+(4*8))(R3), F28 \
|
||||
MOVD ((offset)+(5*8))(R3), F29 \
|
||||
MOVD ((offset)+(6*8))(R3), F30 \
|
||||
MOVD ((offset)+(7*8))(R3), F31
|
||||
6
vendor/github.com/ebitengine/purego/cgo.go
generated
vendored
6
vendor/github.com/ebitengine/purego/cgo.go
generated
vendored
@@ -1,14 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build cgo && (darwin || freebsd || linux)
|
||||
//go:build cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package purego
|
||||
|
||||
// if CGO_ENABLED=1 import the Cgo runtime to ensure that it is set up properly.
|
||||
// This is required since some frameworks need TLS setup the C way which Go doesn't do.
|
||||
// We currently don't support ios in fakecgo mode so force Cgo or fail
|
||||
// Even if CGO_ENABLED=1 the Cgo runtime is not imported unless `import "C"` is used.
|
||||
// We currently don't support ios in fakecgo mode so force Cgo or fail.
|
||||
// Even if CGO_ENABLED=1 the Cgo runtime is not imported unless `import "C"` is used,
|
||||
// which will import this package automatically. Normally this isn't an issue since it
|
||||
// usually isn't possible to call into C without using that import. However, with purego
|
||||
// it is since we don't use `import "C"`!
|
||||
|
||||
2
vendor/github.com/ebitengine/purego/dlerror.go
generated
vendored
2
vendor/github.com/ebitengine/purego/dlerror.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
//go:build darwin || freebsd || linux || netbsd
|
||||
|
||||
package purego
|
||||
|
||||
|
||||
2
vendor/github.com/ebitengine/purego/dlfcn.go
generated
vendored
2
vendor/github.com/ebitengine/purego/dlfcn.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build (darwin || freebsd || linux) && !android && !faketime
|
||||
//go:build (darwin || freebsd || linux || netbsd) && !android && !faketime
|
||||
|
||||
package purego
|
||||
|
||||
|
||||
1
vendor/github.com/ebitengine/purego/dlfcn_darwin.go
generated
vendored
1
vendor/github.com/ebitengine/purego/dlfcn_darwin.go
generated
vendored
@@ -17,3 +17,4 @@ const (
|
||||
//go:cgo_import_dynamic purego_dlsym dlsym "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_dlerror dlerror "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_dlclose dlclose "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_error __error "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
15
vendor/github.com/ebitengine/purego/dlfcn_netbsd.go
generated
vendored
Normal file
15
vendor/github.com/ebitengine/purego/dlfcn_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
// Source for constants: https://github.com/NetBSD/src/blob/trunk/include/dlfcn.h
|
||||
|
||||
const (
|
||||
intSize = 32 << (^uint(0) >> 63) // 32 or 64
|
||||
RTLD_DEFAULT = 1<<intSize - 2 // Pseudo-handle for dlsym so search for any loaded symbol
|
||||
RTLD_LAZY = 0x00000001 // Relocations are performed at an implementation-dependent time.
|
||||
RTLD_NOW = 0x00000002 // Relocations are performed when the object is loaded.
|
||||
RTLD_LOCAL = 0x00000000 // All symbols are not made available for relocation processing by other modules.
|
||||
RTLD_GLOBAL = 0x00000100 // All symbols are available for relocation processing of other modules.
|
||||
)
|
||||
9
vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go
generated
vendored
Normal file
9
vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
//go:cgo_import_dynamic purego_dlopen dlopen "libc.so"
|
||||
//go:cgo_import_dynamic purego_dlsym dlsym "libc.so"
|
||||
//go:cgo_import_dynamic purego_dlerror dlerror "libc.so"
|
||||
//go:cgo_import_dynamic purego_dlclose dlclose "libc.so"
|
||||
6
vendor/github.com/ebitengine/purego/dlfcn_stubs.s
generated
vendored
6
vendor/github.com/ebitengine/purego/dlfcn_stubs.s
generated
vendored
@@ -1,26 +1,22 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || !cgo && (freebsd || linux) && !faketime
|
||||
//go:build darwin || !cgo && (freebsd || linux || netbsd) && !faketime
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func dlopen(path *byte, mode int) (ret uintptr)
|
||||
TEXT dlopen(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlopen(SB)
|
||||
RET
|
||||
|
||||
// func dlsym(handle uintptr, symbol *byte) (ret uintptr)
|
||||
TEXT dlsym(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlsym(SB)
|
||||
RET
|
||||
|
||||
// func dlerror() (ret *byte)
|
||||
TEXT dlerror(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlerror(SB)
|
||||
RET
|
||||
|
||||
// func dlclose(handle uintptr) (ret int)
|
||||
TEXT dlclose(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_dlclose(SB)
|
||||
RET
|
||||
|
||||
305
vendor/github.com/ebitengine/purego/func.go
generated
vendored
305
vendor/github.com/ebitengine/purego/func.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
//go:build darwin || freebsd || linux || netbsd || windows
|
||||
|
||||
package purego
|
||||
|
||||
@@ -10,14 +10,25 @@ import (
|
||||
"math"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"sync"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego/internal/strings"
|
||||
"github.com/ebitengine/purego/internal/xreflect"
|
||||
)
|
||||
|
||||
const (
|
||||
align8ByteMask = 7 // Mask for 8-byte alignment: (val + 7) &^ 7
|
||||
align8ByteSize = 8 // 8-byte alignment boundary
|
||||
)
|
||||
|
||||
var thePool = sync.Pool{New: func() any {
|
||||
return new(syscall15Args)
|
||||
}}
|
||||
|
||||
// RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name).
|
||||
// It panics if it can't find the name symbol.
|
||||
func RegisterLibFunc(fptr interface{}, handle uintptr, name string) {
|
||||
func RegisterLibFunc(fptr any, handle uintptr, name string) {
|
||||
sym, err := loadSymbol(handle, name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -53,14 +64,14 @@ func RegisterLibFunc(fptr interface{}, handle uintptr, name string) {
|
||||
// int64 <=> int64_t
|
||||
// float32 <=> float
|
||||
// float64 <=> double
|
||||
// struct <=> struct (WIP - darwin only)
|
||||
// struct <=> struct (darwin amd64/arm64, linux amd64/arm64)
|
||||
// func <=> C function
|
||||
// unsafe.Pointer, *T <=> void*
|
||||
// []T => void*
|
||||
//
|
||||
// There is a special case when the last argument of fptr is a variadic interface (or []interface}
|
||||
// it will be expanded into a call to the C function as if it had the arguments in that slice.
|
||||
// This means that using arg ...interface{} is like a cast to the function with the arguments inside arg.
|
||||
// This means that using arg ...any is like a cast to the function with the arguments inside arg.
|
||||
// This is not the same as C variadic.
|
||||
//
|
||||
// # Memory
|
||||
@@ -88,6 +99,9 @@ func RegisterLibFunc(fptr interface{}, handle uintptr, name string) {
|
||||
// it does not support aligning fields properly. It is therefore the responsibility of the caller to ensure
|
||||
// that all padding is added to the Go struct to match the C one. See `BoolStructFn` in struct_test.go for an example.
|
||||
//
|
||||
// On Darwin ARM64, purego handles proper alignment of struct arguments when passing them on the stack,
|
||||
// following the C ABI's byte-level packing rules.
|
||||
//
|
||||
// # Example
|
||||
//
|
||||
// All functions below call this C function:
|
||||
@@ -105,7 +119,8 @@ func RegisterLibFunc(fptr interface{}, handle uintptr, name string) {
|
||||
// defer free(mustFree)
|
||||
//
|
||||
// [Cgo rules]: https://pkg.go.dev/cmd/cgo#hdr-Go_references_to_C
|
||||
func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
func RegisterFunc(fptr any, cfn uintptr) {
|
||||
const is32bit = unsafe.Sizeof(uintptr(0)) == 4
|
||||
fn := reflect.ValueOf(fptr).Elem()
|
||||
ty := fn.Type()
|
||||
if ty.Kind() != reflect.Func {
|
||||
@@ -118,7 +133,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
panic("purego: cfn is nil")
|
||||
}
|
||||
if ty.NumOut() == 1 && (ty.Out(0).Kind() == reflect.Float32 || ty.Out(0).Kind() == reflect.Float64) &&
|
||||
runtime.GOARCH != "arm64" && runtime.GOARCH != "amd64" {
|
||||
runtime.GOARCH != "arm" && runtime.GOARCH != "arm64" && runtime.GOARCH != "386" && runtime.GOARCH != "amd64" && runtime.GOARCH != "loong64" && runtime.GOARCH != "ppc64le" && runtime.GOARCH != "riscv64" && runtime.GOARCH != "s390x" {
|
||||
panic("purego: float returns are not supported")
|
||||
}
|
||||
{
|
||||
@@ -152,19 +167,13 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
stack++
|
||||
}
|
||||
case reflect.Float32, reflect.Float64:
|
||||
const is32bit = unsafe.Sizeof(uintptr(0)) == 4
|
||||
if is32bit {
|
||||
panic("purego: floats only supported on 64bit platforms")
|
||||
}
|
||||
if floats < numOfFloats {
|
||||
if floats < numOfFloatRegisters() {
|
||||
floats++
|
||||
} else {
|
||||
stack++
|
||||
}
|
||||
case reflect.Struct:
|
||||
if runtime.GOOS != "darwin" || (runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64") {
|
||||
panic("purego: struct arguments are only supported on darwin amd64 & arm64")
|
||||
}
|
||||
ensureStructSupportedForRegisterFunc()
|
||||
if arg.Size() == 0 {
|
||||
continue
|
||||
}
|
||||
@@ -183,9 +192,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
}
|
||||
}
|
||||
if ty.NumOut() == 1 && ty.Out(0).Kind() == reflect.Struct {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: struct return values only supported on darwin arm64 & amd64")
|
||||
}
|
||||
ensureStructSupportedForRegisterFunc()
|
||||
outType := ty.Out(0)
|
||||
checkStructFieldsSupported(outType)
|
||||
if runtime.GOARCH == "amd64" && outType.Size() > maxRegAllocStructSize {
|
||||
@@ -194,27 +201,29 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
ints++
|
||||
}
|
||||
}
|
||||
|
||||
sizeOfStack := maxArgs - numOfIntegerRegisters()
|
||||
if stack > sizeOfStack {
|
||||
panic("purego: too many arguments")
|
||||
}
|
||||
}
|
||||
v := reflect.MakeFunc(ty, func(args []reflect.Value) (results []reflect.Value) {
|
||||
if len(args) > 0 {
|
||||
if variadic, ok := args[len(args)-1].Interface().([]interface{}); ok {
|
||||
// subtract one from args bc the last argument in args is []interface{}
|
||||
// which we are currently expanding
|
||||
tmp := make([]reflect.Value, len(args)-1+len(variadic))
|
||||
n := copy(tmp, args[:len(args)-1])
|
||||
for i, v := range variadic {
|
||||
tmp[n+i] = reflect.ValueOf(v)
|
||||
}
|
||||
args = tmp
|
||||
// On Darwin ARM64, use byte-based validation since arguments pack efficiently.
|
||||
// See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
|
||||
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||
stackBytes := estimateStackBytes(ty)
|
||||
maxStackBytes := sizeOfStack * 8
|
||||
if stackBytes > maxStackBytes {
|
||||
panic("purego: too many stack arguments")
|
||||
}
|
||||
} else {
|
||||
if stack > sizeOfStack {
|
||||
panic("purego: too many stack arguments")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
v := reflect.MakeFunc(ty, func(args []reflect.Value) (results []reflect.Value) {
|
||||
var sysargs [maxArgs]uintptr
|
||||
stack := sysargs[numOfIntegerRegisters():]
|
||||
var floats [numOfFloats]uintptr
|
||||
// Use maxArgs instead of numOfFloatRegisters() to keep this code path allocation-free,
|
||||
// since numOfFloatRegisters() is a function call, not a constant.
|
||||
// maxArgs is always greater than or equal to numOfFloatRegisters() so this is safe.
|
||||
var floats [maxArgs]uintptr
|
||||
var numInts int
|
||||
var numFloats int
|
||||
var numStack int
|
||||
@@ -222,7 +231,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
|
||||
// Windows arm64 uses the same calling convention as macOS and Linux
|
||||
addStack = func(x uintptr) {
|
||||
stack[numStack] = x
|
||||
sysargs[numOfIntegerRegisters()+numStack] = x
|
||||
numStack++
|
||||
}
|
||||
addInt = func(x uintptr) {
|
||||
@@ -234,7 +243,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
}
|
||||
}
|
||||
addFloat = func(x uintptr) {
|
||||
if numFloats < len(floats) {
|
||||
if numFloats < numOfFloatRegisters() {
|
||||
floats[numFloats] = x
|
||||
numFloats++
|
||||
} else {
|
||||
@@ -255,15 +264,16 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
addFloat = addStack
|
||||
}
|
||||
|
||||
var keepAlive []interface{}
|
||||
var keepAlive []any
|
||||
defer func() {
|
||||
runtime.KeepAlive(keepAlive)
|
||||
runtime.KeepAlive(args)
|
||||
}()
|
||||
var syscall syscall15Args
|
||||
|
||||
var arm64_r8 uintptr
|
||||
if ty.NumOut() == 1 && ty.Out(0).Kind() == reflect.Struct {
|
||||
outType := ty.Out(0)
|
||||
if runtime.GOARCH == "amd64" && outType.Size() > maxRegAllocStructSize {
|
||||
if (runtime.GOARCH == "amd64" || runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") && outType.Size() > maxRegAllocStructSize {
|
||||
val := reflect.New(outType)
|
||||
keepAlive = append(keepAlive, val)
|
||||
addInt(val.Pointer())
|
||||
@@ -272,53 +282,46 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
if !isAllFloats || numFields > 4 {
|
||||
val := reflect.New(outType)
|
||||
keepAlive = append(keepAlive, val)
|
||||
syscall.arm64_r8 = val.Pointer()
|
||||
arm64_r8 = val.Pointer()
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, v := range args {
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
ptr := strings.CString(v.String())
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
addInt(uintptr(unsafe.Pointer(ptr)))
|
||||
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
addInt(uintptr(v.Uint()))
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
addInt(uintptr(v.Int()))
|
||||
case reflect.Ptr, reflect.UnsafePointer, reflect.Slice:
|
||||
// There is no need to keepAlive this pointer separately because it is kept alive in the args variable
|
||||
addInt(v.Pointer())
|
||||
case reflect.Func:
|
||||
addInt(NewCallback(v.Interface()))
|
||||
case reflect.Bool:
|
||||
if v.Bool() {
|
||||
addInt(1)
|
||||
} else {
|
||||
addInt(0)
|
||||
for i, v := range args {
|
||||
if variadic, ok := xreflect.TypeAssert[[]any](args[i]); ok {
|
||||
if i != len(args)-1 {
|
||||
panic("purego: can only expand last parameter")
|
||||
}
|
||||
case reflect.Float32:
|
||||
addFloat(uintptr(math.Float32bits(float32(v.Float()))))
|
||||
case reflect.Float64:
|
||||
addFloat(uintptr(math.Float64bits(v.Float())))
|
||||
case reflect.Struct:
|
||||
keepAlive = addStruct(v, &numInts, &numFloats, &numStack, addInt, addFloat, addStack, keepAlive)
|
||||
default:
|
||||
panic("purego: unsupported kind: " + v.Kind().String())
|
||||
for _, x := range variadic {
|
||||
keepAlive = addValue(reflect.ValueOf(x), keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack)
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Check if we need to start Darwin ARM64 C-style stack packing
|
||||
if runtime.GOARCH == "arm64" && runtime.GOOS == "darwin" && shouldBundleStackArgs(v, numInts, numFloats) {
|
||||
// Collect and separate remaining args into register vs stack
|
||||
stackArgs, newKeepAlive := collectStackArgs(args, i, numInts, numFloats,
|
||||
keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack)
|
||||
keepAlive = newKeepAlive
|
||||
|
||||
// Bundle stack arguments with C-style packing
|
||||
bundleStackArgs(stackArgs, addStack)
|
||||
break
|
||||
}
|
||||
keepAlive = addValue(v, keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack)
|
||||
}
|
||||
if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
|
||||
|
||||
syscall := thePool.Get().(*syscall15Args)
|
||||
defer thePool.Put(syscall)
|
||||
|
||||
if runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x" {
|
||||
syscall.Set(cfn, sysargs[:], floats[:], 0)
|
||||
runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall))
|
||||
} else if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" {
|
||||
// Use the normal arm64 calling convention even on Windows
|
||||
syscall = syscall15Args{
|
||||
cfn,
|
||||
sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], sysargs[5],
|
||||
sysargs[6], sysargs[7], sysargs[8], sysargs[9], sysargs[10], sysargs[11],
|
||||
sysargs[12], sysargs[13], sysargs[14],
|
||||
floats[0], floats[1], floats[2], floats[3], floats[4], floats[5], floats[6], floats[7],
|
||||
syscall.arm64_r8,
|
||||
}
|
||||
runtime_cgocall(syscall15XABI0, unsafe.Pointer(&syscall))
|
||||
syscall.Set(cfn, sysargs[:], floats[:], arm64_r8)
|
||||
runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall))
|
||||
} else {
|
||||
*syscall = syscall15Args{}
|
||||
// This is a fallback for Windows amd64, 386, and arm. Note this may not support floats
|
||||
syscall.a1, syscall.a2, _ = syscall_syscall15X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4],
|
||||
sysargs[5], sysargs[6], sysargs[7], sysargs[8], sysargs[9], sysargs[10], sysargs[11],
|
||||
@@ -351,21 +354,89 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
|
||||
case reflect.Float32:
|
||||
// NOTE: syscall.r2 is only the floating return value on 64bit platforms.
|
||||
// On 32bit platforms syscall.r2 is the upper part of a 64bit return.
|
||||
v.SetFloat(float64(math.Float32frombits(uint32(syscall.f1))))
|
||||
// On 386, x87 FPU returns floats as float64 in ST(0), so we read as float64 and convert.
|
||||
// On PPC64LE, C ABI converts float32 to double in FPR, so we read as float64.
|
||||
// On S390X (big-endian), float32 is in upper 32 bits of the 64-bit FP register.
|
||||
switch runtime.GOARCH {
|
||||
case "386":
|
||||
v.SetFloat(math.Float64frombits(uint64(syscall.f1) | (uint64(syscall.f2) << 32)))
|
||||
case "ppc64le":
|
||||
v.SetFloat(math.Float64frombits(uint64(syscall.f1)))
|
||||
case "s390x":
|
||||
// S390X is big-endian: float32 in upper 32 bits of 64-bit register
|
||||
v.SetFloat(float64(math.Float32frombits(uint32(syscall.f1 >> 32))))
|
||||
default:
|
||||
v.SetFloat(float64(math.Float32frombits(uint32(syscall.f1))))
|
||||
}
|
||||
case reflect.Float64:
|
||||
// NOTE: syscall.r2 is only the floating return value on 64bit platforms.
|
||||
// On 32bit platforms syscall.r2 is the upper part of a 64bit return.
|
||||
v.SetFloat(math.Float64frombits(uint64(syscall.f1)))
|
||||
if is32bit {
|
||||
v.SetFloat(math.Float64frombits(uint64(syscall.f1) | (uint64(syscall.f2) << 32)))
|
||||
} else {
|
||||
v.SetFloat(math.Float64frombits(uint64(syscall.f1)))
|
||||
}
|
||||
case reflect.Struct:
|
||||
v = getStruct(outType, syscall)
|
||||
v = getStruct(outType, *syscall)
|
||||
default:
|
||||
panic("purego: unsupported return kind: " + outType.Kind().String())
|
||||
}
|
||||
return []reflect.Value{v}
|
||||
if len(args) > 0 {
|
||||
// reuse args slice instead of allocating one when possible
|
||||
args[0] = v
|
||||
return args[:1]
|
||||
} else {
|
||||
return []reflect.Value{v}
|
||||
}
|
||||
})
|
||||
fn.Set(v)
|
||||
}
|
||||
|
||||
func addValue(v reflect.Value, keepAlive []any, addInt func(x uintptr), addFloat func(x uintptr), addStack func(x uintptr), numInts *int, numFloats *int, numStack *int) []any {
|
||||
const is32bit = unsafe.Sizeof(uintptr(0)) == 4
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
ptr := strings.CString(v.String())
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
addInt(uintptr(unsafe.Pointer(ptr)))
|
||||
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
addInt(uintptr(v.Uint()))
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
addInt(uintptr(v.Int()))
|
||||
case reflect.Ptr, reflect.UnsafePointer, reflect.Slice:
|
||||
// There is no need to keepAlive this pointer separately because it is kept alive in the args variable
|
||||
addInt(v.Pointer())
|
||||
case reflect.Func:
|
||||
addInt(NewCallback(v.Interface()))
|
||||
case reflect.Bool:
|
||||
if v.Bool() {
|
||||
addInt(1)
|
||||
} else {
|
||||
addInt(0)
|
||||
}
|
||||
case reflect.Float32:
|
||||
// On S390X big-endian, float32 goes in upper 32 bits of 64-bit FP register
|
||||
if runtime.GOARCH == "s390x" {
|
||||
addFloat(uintptr(math.Float32bits(float32(v.Float()))) << 32)
|
||||
} else {
|
||||
addFloat(uintptr(math.Float32bits(float32(v.Float()))))
|
||||
}
|
||||
case reflect.Float64:
|
||||
if is32bit {
|
||||
bits := math.Float64bits(v.Float())
|
||||
addFloat(uintptr(bits))
|
||||
addFloat(uintptr(bits >> 32))
|
||||
} else {
|
||||
addFloat(uintptr(math.Float64bits(v.Float())))
|
||||
}
|
||||
case reflect.Struct:
|
||||
keepAlive = addStruct(v, numInts, numFloats, numStack, addInt, addFloat, addStack, keepAlive)
|
||||
default:
|
||||
panic("purego: unsupported kind: " + v.Kind().String())
|
||||
}
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// maxRegAllocStructSize is the biggest a struct can be while still fitting in registers.
|
||||
// if it is bigger than this than enough space must be allocated on the heap and then passed into
|
||||
// the function as the first parameter on amd64 or in R8 on arm64.
|
||||
@@ -411,26 +482,90 @@ func checkStructFieldsSupported(ty reflect.Type) {
|
||||
switch f.Kind() {
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
|
||||
reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
|
||||
reflect.Uintptr, reflect.Ptr, reflect.UnsafePointer, reflect.Float64, reflect.Float32:
|
||||
reflect.Uintptr, reflect.Ptr, reflect.UnsafePointer, reflect.Float64, reflect.Float32,
|
||||
reflect.Bool:
|
||||
default:
|
||||
panic(fmt.Sprintf("purego: struct field type %s is not supported", f))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ensureStructSupportedForRegisterFunc() {
|
||||
if runtime.GOARCH != "amd64" && runtime.GOARCH != "arm64" {
|
||||
panic("purego: struct arguments are only supported on amd64 and arm64")
|
||||
}
|
||||
if runtime.GOOS != "darwin" && runtime.GOOS != "linux" {
|
||||
panic("purego: struct arguments are only supported on darwin and linux")
|
||||
}
|
||||
}
|
||||
|
||||
func roundUpTo8(val uintptr) uintptr {
|
||||
return (val + 7) &^ 7
|
||||
return (val + align8ByteMask) &^ align8ByteMask
|
||||
}
|
||||
|
||||
func numOfFloatRegisters() int {
|
||||
switch runtime.GOARCH {
|
||||
case "amd64", "arm64", "loong64", "ppc64le", "riscv64":
|
||||
return 8
|
||||
case "s390x":
|
||||
return 4
|
||||
case "arm":
|
||||
return 16
|
||||
case "386":
|
||||
// i386 SysV ABI passes all arguments on the stack, including floats
|
||||
return 0
|
||||
default:
|
||||
// since this platform isn't supported and can therefore only access
|
||||
// integer registers it is safest to return 8
|
||||
return 8
|
||||
}
|
||||
}
|
||||
|
||||
func numOfIntegerRegisters() int {
|
||||
switch runtime.GOARCH {
|
||||
case "arm64":
|
||||
case "arm64", "loong64", "ppc64le", "riscv64":
|
||||
return 8
|
||||
case "amd64":
|
||||
return 6
|
||||
case "s390x":
|
||||
// S390X uses R2-R6 for integer arguments
|
||||
return 5
|
||||
case "arm":
|
||||
return 4
|
||||
case "386":
|
||||
// i386 SysV ABI passes all arguments on the stack
|
||||
return 0
|
||||
default:
|
||||
// since this platform isn't supported and can therefore only access
|
||||
// integer registers it is fine to return the maxArgs
|
||||
return maxArgs
|
||||
}
|
||||
}
|
||||
|
||||
// estimateStackBytes estimates stack bytes needed for Darwin ARM64 validation.
|
||||
// This is a conservative estimate used only for early error detection.
|
||||
func estimateStackBytes(ty reflect.Type) int {
|
||||
var numInts, numFloats int
|
||||
var stackBytes int
|
||||
|
||||
for i := 0; i < ty.NumIn(); i++ {
|
||||
arg := ty.In(i)
|
||||
size := int(arg.Size())
|
||||
|
||||
// Check if this goes to register or stack
|
||||
usesInt := arg.Kind() != reflect.Float32 && arg.Kind() != reflect.Float64
|
||||
if usesInt && numInts < numOfIntegerRegisters() {
|
||||
numInts++
|
||||
} else if !usesInt && numFloats < numOfFloatRegisters() {
|
||||
numFloats++
|
||||
} else {
|
||||
// Goes to stack - accumulate total bytes
|
||||
stackBytes += size
|
||||
}
|
||||
}
|
||||
// Round total to 8-byte boundary
|
||||
if stackBytes > 0 && stackBytes%align8ByteSize != 0 {
|
||||
stackBytes = int(roundUpTo8(uintptr(stackBytes)))
|
||||
}
|
||||
return stackBytes
|
||||
}
|
||||
|
||||
6
vendor/github.com/ebitengine/purego/gen.go
generated
vendored
Normal file
6
vendor/github.com/ebitengine/purego/gen.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
//go:generate go run wincallback.go
|
||||
2
vendor/github.com/ebitengine/purego/go_runtime.go
generated
vendored
2
vendor/github.com/ebitengine/purego/go_runtime.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
//go:build darwin || freebsd || linux || netbsd || windows
|
||||
|
||||
package purego
|
||||
|
||||
|
||||
4
vendor/github.com/ebitengine/purego/internal/cgo/dlfcn_cgo_unix.go
generated
vendored
4
vendor/github.com/ebitengine/purego/internal/cgo/dlfcn_cgo_unix.go
generated
vendored
@@ -1,12 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors
|
||||
|
||||
//go:build freebsd || linux
|
||||
//go:build freebsd || linux || netbsd
|
||||
|
||||
package cgo
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -ldl
|
||||
#cgo !netbsd LDFLAGS: -ldl
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
4
vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go
generated
vendored
4
vendor/github.com/ebitengine/purego/internal/cgo/syscall_cgo_unix.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build freebsd || (linux && !(arm64 || amd64))
|
||||
//go:build freebsd || (linux && !(386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64)) || netbsd
|
||||
|
||||
package cgo
|
||||
|
||||
@@ -9,7 +9,7 @@ package cgo
|
||||
// because Cgo and assembly files can't be in the same package.
|
||||
|
||||
/*
|
||||
#cgo LDFLAGS: -ldl
|
||||
#cgo !netbsd LDFLAGS: -ldl
|
||||
|
||||
#include <stdint.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
60
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_loong64.h
generated
vendored
Normal file
60
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_loong64.h
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R22_TO_R31(offset) saves R22 ~ R31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+9*8)(R3).
|
||||
//
|
||||
// SAVE_F24_TO_F31(offset) saves F24 ~ F31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+7*8)(R3).
|
||||
//
|
||||
// Note: g is R22
|
||||
|
||||
#define SAVE_R22_TO_R31(offset) \
|
||||
MOVV g, ((offset)+(0*8))(R3) \
|
||||
MOVV R23, ((offset)+(1*8))(R3) \
|
||||
MOVV R24, ((offset)+(2*8))(R3) \
|
||||
MOVV R25, ((offset)+(3*8))(R3) \
|
||||
MOVV R26, ((offset)+(4*8))(R3) \
|
||||
MOVV R27, ((offset)+(5*8))(R3) \
|
||||
MOVV R28, ((offset)+(6*8))(R3) \
|
||||
MOVV R29, ((offset)+(7*8))(R3) \
|
||||
MOVV R30, ((offset)+(8*8))(R3) \
|
||||
MOVV R31, ((offset)+(9*8))(R3)
|
||||
|
||||
#define SAVE_F24_TO_F31(offset) \
|
||||
MOVD F24, ((offset)+(0*8))(R3) \
|
||||
MOVD F25, ((offset)+(1*8))(R3) \
|
||||
MOVD F26, ((offset)+(2*8))(R3) \
|
||||
MOVD F27, ((offset)+(3*8))(R3) \
|
||||
MOVD F28, ((offset)+(4*8))(R3) \
|
||||
MOVD F29, ((offset)+(5*8))(R3) \
|
||||
MOVD F30, ((offset)+(6*8))(R3) \
|
||||
MOVD F31, ((offset)+(7*8))(R3)
|
||||
|
||||
#define RESTORE_R22_TO_R31(offset) \
|
||||
MOVV ((offset)+(0*8))(R3), g \
|
||||
MOVV ((offset)+(1*8))(R3), R23 \
|
||||
MOVV ((offset)+(2*8))(R3), R24 \
|
||||
MOVV ((offset)+(3*8))(R3), R25 \
|
||||
MOVV ((offset)+(4*8))(R3), R26 \
|
||||
MOVV ((offset)+(5*8))(R3), R27 \
|
||||
MOVV ((offset)+(6*8))(R3), R28 \
|
||||
MOVV ((offset)+(7*8))(R3), R29 \
|
||||
MOVV ((offset)+(8*8))(R3), R30 \
|
||||
MOVV ((offset)+(9*8))(R3), R31
|
||||
|
||||
#define RESTORE_F24_TO_F31(offset) \
|
||||
MOVD ((offset)+(0*8))(R3), F24 \
|
||||
MOVD ((offset)+(1*8))(R3), F25 \
|
||||
MOVD ((offset)+(2*8))(R3), F26 \
|
||||
MOVD ((offset)+(3*8))(R3), F27 \
|
||||
MOVD ((offset)+(4*8))(R3), F28 \
|
||||
MOVD ((offset)+(5*8))(R3), F29 \
|
||||
MOVD ((offset)+(6*8))(R3), F30 \
|
||||
MOVD ((offset)+(7*8))(R3), F31
|
||||
195
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_ppc64x.h
generated
vendored
Normal file
195
vendor/github.com/ebitengine/purego/internal/fakecgo/abi_ppc64x.h
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI
|
||||
//
|
||||
// On PPC64/ELFv2 targets, the following registers are callee
|
||||
// saved when called from C. They must be preserved before
|
||||
// calling into Go which does not preserve any of them.
|
||||
//
|
||||
// R14-R31
|
||||
// CR2-4
|
||||
// VR20-31
|
||||
// F14-F31
|
||||
//
|
||||
// xcoff(aix) and ELFv1 are similar, but may only require a
|
||||
// subset of these.
|
||||
//
|
||||
// These macros assume a 16 byte aligned stack pointer. This
|
||||
// is required by ELFv1, ELFv2, and AIX PPC64.
|
||||
|
||||
#define SAVE_GPR_SIZE (18*8)
|
||||
#define SAVE_GPR(offset) \
|
||||
MOVD R14, (offset+8*0)(R1) \
|
||||
MOVD R15, (offset+8*1)(R1) \
|
||||
MOVD R16, (offset+8*2)(R1) \
|
||||
MOVD R17, (offset+8*3)(R1) \
|
||||
MOVD R18, (offset+8*4)(R1) \
|
||||
MOVD R19, (offset+8*5)(R1) \
|
||||
MOVD R20, (offset+8*6)(R1) \
|
||||
MOVD R21, (offset+8*7)(R1) \
|
||||
MOVD R22, (offset+8*8)(R1) \
|
||||
MOVD R23, (offset+8*9)(R1) \
|
||||
MOVD R24, (offset+8*10)(R1) \
|
||||
MOVD R25, (offset+8*11)(R1) \
|
||||
MOVD R26, (offset+8*12)(R1) \
|
||||
MOVD R27, (offset+8*13)(R1) \
|
||||
MOVD R28, (offset+8*14)(R1) \
|
||||
MOVD R29, (offset+8*15)(R1) \
|
||||
MOVD g, (offset+8*16)(R1) \
|
||||
MOVD R31, (offset+8*17)(R1)
|
||||
|
||||
#define RESTORE_GPR(offset) \
|
||||
MOVD (offset+8*0)(R1), R14 \
|
||||
MOVD (offset+8*1)(R1), R15 \
|
||||
MOVD (offset+8*2)(R1), R16 \
|
||||
MOVD (offset+8*3)(R1), R17 \
|
||||
MOVD (offset+8*4)(R1), R18 \
|
||||
MOVD (offset+8*5)(R1), R19 \
|
||||
MOVD (offset+8*6)(R1), R20 \
|
||||
MOVD (offset+8*7)(R1), R21 \
|
||||
MOVD (offset+8*8)(R1), R22 \
|
||||
MOVD (offset+8*9)(R1), R23 \
|
||||
MOVD (offset+8*10)(R1), R24 \
|
||||
MOVD (offset+8*11)(R1), R25 \
|
||||
MOVD (offset+8*12)(R1), R26 \
|
||||
MOVD (offset+8*13)(R1), R27 \
|
||||
MOVD (offset+8*14)(R1), R28 \
|
||||
MOVD (offset+8*15)(R1), R29 \
|
||||
MOVD (offset+8*16)(R1), g \
|
||||
MOVD (offset+8*17)(R1), R31
|
||||
|
||||
#define SAVE_FPR_SIZE (18*8)
|
||||
#define SAVE_FPR(offset) \
|
||||
FMOVD F14, (offset+8*0)(R1) \
|
||||
FMOVD F15, (offset+8*1)(R1) \
|
||||
FMOVD F16, (offset+8*2)(R1) \
|
||||
FMOVD F17, (offset+8*3)(R1) \
|
||||
FMOVD F18, (offset+8*4)(R1) \
|
||||
FMOVD F19, (offset+8*5)(R1) \
|
||||
FMOVD F20, (offset+8*6)(R1) \
|
||||
FMOVD F21, (offset+8*7)(R1) \
|
||||
FMOVD F22, (offset+8*8)(R1) \
|
||||
FMOVD F23, (offset+8*9)(R1) \
|
||||
FMOVD F24, (offset+8*10)(R1) \
|
||||
FMOVD F25, (offset+8*11)(R1) \
|
||||
FMOVD F26, (offset+8*12)(R1) \
|
||||
FMOVD F27, (offset+8*13)(R1) \
|
||||
FMOVD F28, (offset+8*14)(R1) \
|
||||
FMOVD F29, (offset+8*15)(R1) \
|
||||
FMOVD F30, (offset+8*16)(R1) \
|
||||
FMOVD F31, (offset+8*17)(R1)
|
||||
|
||||
#define RESTORE_FPR(offset) \
|
||||
FMOVD (offset+8*0)(R1), F14 \
|
||||
FMOVD (offset+8*1)(R1), F15 \
|
||||
FMOVD (offset+8*2)(R1), F16 \
|
||||
FMOVD (offset+8*3)(R1), F17 \
|
||||
FMOVD (offset+8*4)(R1), F18 \
|
||||
FMOVD (offset+8*5)(R1), F19 \
|
||||
FMOVD (offset+8*6)(R1), F20 \
|
||||
FMOVD (offset+8*7)(R1), F21 \
|
||||
FMOVD (offset+8*8)(R1), F22 \
|
||||
FMOVD (offset+8*9)(R1), F23 \
|
||||
FMOVD (offset+8*10)(R1), F24 \
|
||||
FMOVD (offset+8*11)(R1), F25 \
|
||||
FMOVD (offset+8*12)(R1), F26 \
|
||||
FMOVD (offset+8*13)(R1), F27 \
|
||||
FMOVD (offset+8*14)(R1), F28 \
|
||||
FMOVD (offset+8*15)(R1), F29 \
|
||||
FMOVD (offset+8*16)(R1), F30 \
|
||||
FMOVD (offset+8*17)(R1), F31
|
||||
|
||||
// Save and restore VR20-31 (aka VSR56-63). These
|
||||
// macros must point to a 16B aligned offset.
|
||||
#define SAVE_VR_SIZE (12*16)
|
||||
#define SAVE_VR(offset, rtmp) \
|
||||
MOVD $(offset+16*0), rtmp \
|
||||
STVX V20, (rtmp)(R1) \
|
||||
MOVD $(offset+16*1), rtmp \
|
||||
STVX V21, (rtmp)(R1) \
|
||||
MOVD $(offset+16*2), rtmp \
|
||||
STVX V22, (rtmp)(R1) \
|
||||
MOVD $(offset+16*3), rtmp \
|
||||
STVX V23, (rtmp)(R1) \
|
||||
MOVD $(offset+16*4), rtmp \
|
||||
STVX V24, (rtmp)(R1) \
|
||||
MOVD $(offset+16*5), rtmp \
|
||||
STVX V25, (rtmp)(R1) \
|
||||
MOVD $(offset+16*6), rtmp \
|
||||
STVX V26, (rtmp)(R1) \
|
||||
MOVD $(offset+16*7), rtmp \
|
||||
STVX V27, (rtmp)(R1) \
|
||||
MOVD $(offset+16*8), rtmp \
|
||||
STVX V28, (rtmp)(R1) \
|
||||
MOVD $(offset+16*9), rtmp \
|
||||
STVX V29, (rtmp)(R1) \
|
||||
MOVD $(offset+16*10), rtmp \
|
||||
STVX V30, (rtmp)(R1) \
|
||||
MOVD $(offset+16*11), rtmp \
|
||||
STVX V31, (rtmp)(R1)
|
||||
|
||||
#define RESTORE_VR(offset, rtmp) \
|
||||
MOVD $(offset+16*0), rtmp \
|
||||
LVX (rtmp)(R1), V20 \
|
||||
MOVD $(offset+16*1), rtmp \
|
||||
LVX (rtmp)(R1), V21 \
|
||||
MOVD $(offset+16*2), rtmp \
|
||||
LVX (rtmp)(R1), V22 \
|
||||
MOVD $(offset+16*3), rtmp \
|
||||
LVX (rtmp)(R1), V23 \
|
||||
MOVD $(offset+16*4), rtmp \
|
||||
LVX (rtmp)(R1), V24 \
|
||||
MOVD $(offset+16*5), rtmp \
|
||||
LVX (rtmp)(R1), V25 \
|
||||
MOVD $(offset+16*6), rtmp \
|
||||
LVX (rtmp)(R1), V26 \
|
||||
MOVD $(offset+16*7), rtmp \
|
||||
LVX (rtmp)(R1), V27 \
|
||||
MOVD $(offset+16*8), rtmp \
|
||||
LVX (rtmp)(R1), V28 \
|
||||
MOVD $(offset+16*9), rtmp \
|
||||
LVX (rtmp)(R1), V29 \
|
||||
MOVD $(offset+16*10), rtmp \
|
||||
LVX (rtmp)(R1), V30 \
|
||||
MOVD $(offset+16*11), rtmp \
|
||||
LVX (rtmp)(R1), V31
|
||||
|
||||
// LR and CR are saved in the caller's frame. The callee must
|
||||
// make space for all other callee-save registers.
|
||||
#define SAVE_ALL_REG_SIZE (SAVE_GPR_SIZE+SAVE_FPR_SIZE+SAVE_VR_SIZE)
|
||||
|
||||
// Stack a frame and save all callee-save registers following the
|
||||
// host OS's ABI. Fortunately, this is identical for AIX, ELFv1, and
|
||||
// ELFv2. All host ABIs require the stack pointer to maintain 16 byte
|
||||
// alignment, and save the callee-save registers in the same places.
|
||||
//
|
||||
// To restate, R1 is assumed to be aligned when this macro is used.
|
||||
// This assumes the caller's frame is compliant with the host ABI.
|
||||
// CR and LR are saved into the caller's frame per the host ABI.
|
||||
// R0 is initialized to $0 as expected by Go.
|
||||
#define STACK_AND_SAVE_HOST_TO_GO_ABI(extra) \
|
||||
MOVD LR, R0 \
|
||||
MOVD R0, 16(R1) \
|
||||
MOVW CR, R0 \
|
||||
MOVD R0, 8(R1) \
|
||||
MOVDU R1, -(extra)-FIXED_FRAME-SAVE_ALL_REG_SIZE(R1) \
|
||||
SAVE_GPR(extra+FIXED_FRAME) \
|
||||
SAVE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
|
||||
SAVE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
|
||||
MOVD $0, R0
|
||||
|
||||
// This unstacks the frame, restoring all callee-save registers
|
||||
// as saved by STACK_AND_SAVE_HOST_TO_GO_ABI.
|
||||
//
|
||||
// R0 is not guaranteed to contain $0 after this macro.
|
||||
#define UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(extra) \
|
||||
RESTORE_GPR(extra+FIXED_FRAME) \
|
||||
RESTORE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
|
||||
RESTORE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
|
||||
ADD $(extra+FIXED_FRAME+SAVE_ALL_REG_SIZE), R1 \
|
||||
MOVD 16(R1), R0 \
|
||||
MOVD R0, LR \
|
||||
MOVD 8(R1), R0 \
|
||||
MOVW R0, CR
|
||||
29
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_386.s
generated
vendored
Normal file
29
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_386.s
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT, $28-16
|
||||
MOVL BP, 24(SP)
|
||||
MOVL BX, 20(SP)
|
||||
MOVL SI, 16(SP)
|
||||
MOVL DI, 12(SP)
|
||||
|
||||
MOVL ctxt+12(FP), AX
|
||||
MOVL AX, 8(SP)
|
||||
MOVL a+4(FP), AX
|
||||
MOVL AX, 4(SP)
|
||||
MOVL fn+0(FP), AX
|
||||
MOVL AX, 0(SP)
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
MOVL 12(SP), DI
|
||||
MOVL 16(SP), SI
|
||||
MOVL 20(SP), BX
|
||||
MOVL 24(SP), BP
|
||||
RET
|
||||
52
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm.s
generated
vendored
Normal file
52
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_arm.s
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
SUB $(8*9), R13 // Reserve space for the floating point registers.
|
||||
|
||||
// The C arguments arrive in R0, R1, R2, and R3. We want to
|
||||
// pass R0, R1, and R3 to Go, so we push those on the stack.
|
||||
// Also, save C callee-save registers R4-R12.
|
||||
MOVM.WP [R0, R1, R3, R4, R5, R6, R7, R8, R9, g, R11, R12], (R13)
|
||||
|
||||
// Finally, save the link register R14. This also puts the
|
||||
// arguments we pushed for cgocallback where they need to be,
|
||||
// starting at 4(R13).
|
||||
MOVW.W R14, -4(R13)
|
||||
|
||||
// Save VFP callee-saved registers D8-D15 (same as S16-S31).
|
||||
// Note: We always save these since we target hard-float ABI.
|
||||
MOVD F8, (13*4+8*1)(R13)
|
||||
MOVD F9, (13*4+8*2)(R13)
|
||||
MOVD F10, (13*4+8*3)(R13)
|
||||
MOVD F11, (13*4+8*4)(R13)
|
||||
MOVD F12, (13*4+8*5)(R13)
|
||||
MOVD F13, (13*4+8*6)(R13)
|
||||
MOVD F14, (13*4+8*7)(R13)
|
||||
MOVD F15, (13*4+8*8)(R13)
|
||||
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
// We set up the arguments to cgocallback when saving registers above.
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
MOVD (13*4+8*1)(R13), F8
|
||||
MOVD (13*4+8*2)(R13), F9
|
||||
MOVD (13*4+8*3)(R13), F10
|
||||
MOVD (13*4+8*4)(R13), F11
|
||||
MOVD (13*4+8*5)(R13), F12
|
||||
MOVD (13*4+8*6)(R13), F13
|
||||
MOVD (13*4+8*7)(R13), F14
|
||||
MOVD (13*4+8*8)(R13), F15
|
||||
|
||||
MOVW.P 4(R13), R14
|
||||
MOVM.IAW (R13), [R0, R1, R3, R4, R5, R6, R7, R8, R9, g, R11, R12]
|
||||
ADD $(8*9), R13
|
||||
MOVW R14, R15
|
||||
40
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_loong64.s
generated
vendored
Normal file
40
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_loong64.s
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_loong64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* We still need to save all callee save register as before, and then
|
||||
* push 3 args for fn (R4, R5, R7), skipping R6.
|
||||
* Also note that at procedure entry in gc world, 8(R29) will be the
|
||||
* first arg.
|
||||
*/
|
||||
|
||||
ADDV $(-23*8), R3
|
||||
MOVV R4, (1*8)(R3) // fn unsafe.Pointer
|
||||
MOVV R5, (2*8)(R3) // a unsafe.Pointer
|
||||
MOVV R7, (3*8)(R3) // ctxt uintptr
|
||||
|
||||
SAVE_R22_TO_R31((4*8))
|
||||
SAVE_F24_TO_F31((14*8))
|
||||
MOVV R1, (22*8)(R3)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
JAL runtime·load_g(SB)
|
||||
|
||||
JAL runtime·cgocallback(SB)
|
||||
|
||||
RESTORE_R22_TO_R31((4*8))
|
||||
RESTORE_F24_TO_F31((14*8))
|
||||
MOVV (22*8)(R3), R1
|
||||
|
||||
ADDV $(23*8), R3
|
||||
|
||||
RET
|
||||
82
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_ppc64le.s
generated
vendored
Normal file
82
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_ppc64le.s
generated
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_ppc64x.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
//
|
||||
// This is a simplified version that only saves GPR and FPR registers,
|
||||
// not vector registers. This keeps the stack frame smaller to avoid
|
||||
// exceeding the nosplit stack limit.
|
||||
//
|
||||
// On PPC64LE ELFv2, callee-save registers are:
|
||||
// R14-R31 (18 GPRs = 144 bytes)
|
||||
// F14-F31 (18 FPRs = 144 bytes)
|
||||
// CR2-CR4 (saved in CR field)
|
||||
//
|
||||
// Stack layout (must be 16-byte aligned):
|
||||
// 32 (FIXED_FRAME) + 24 (args) + 144 (GPR) + 144 (FPR) = 344
|
||||
// Rounded to 352 for 16-byte alignment.
|
||||
|
||||
#define FIXED_FRAME 32
|
||||
#define SAVE_SIZE 352
|
||||
#define GPR_OFFSET (FIXED_FRAME+24)
|
||||
#define FPR_OFFSET (GPR_OFFSET+SAVE_GPR_SIZE)
|
||||
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
// Save LR and CR in caller's frame per ELFv2 ABI
|
||||
MOVD LR, R0
|
||||
MOVD R0, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
// Allocate our stack frame
|
||||
MOVDU R1, -SAVE_SIZE(R1)
|
||||
|
||||
// Save TOC (R2) in case needed
|
||||
MOVD R2, 24(R1)
|
||||
|
||||
// Save callee-save GPRs
|
||||
SAVE_GPR(GPR_OFFSET)
|
||||
|
||||
// Save callee-save FPRs
|
||||
SAVE_FPR(FPR_OFFSET)
|
||||
|
||||
// Initialize R0 to 0 as expected by Go
|
||||
MOVD $0, R0
|
||||
|
||||
// Load the current g.
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
// Set up arguments for cgocallback
|
||||
MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
|
||||
MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
|
||||
|
||||
// Skip R5 = n uint32
|
||||
MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
// Restore callee-save FPRs
|
||||
RESTORE_FPR(FPR_OFFSET)
|
||||
|
||||
// Restore callee-save GPRs
|
||||
RESTORE_GPR(GPR_OFFSET)
|
||||
|
||||
// Restore TOC
|
||||
MOVD 24(R1), R2
|
||||
|
||||
// Deallocate stack frame
|
||||
ADD $SAVE_SIZE, R1
|
||||
|
||||
// Restore LR and CR from caller's frame
|
||||
MOVD 16(R1), R0
|
||||
MOVD R0, LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
|
||||
RET
|
||||
78
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_riscv64.s
generated
vendored
Normal file
78
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_riscv64.s
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* Push arguments for fn (X10, X11, X13), along with all callee-save
|
||||
* registers. Note that at procedure entry the first argument is at
|
||||
* 8(X2).
|
||||
*/
|
||||
ADD $(-8*29), X2
|
||||
MOV X10, (8*1)(X2) // fn unsafe.Pointer
|
||||
MOV X11, (8*2)(X2) // a unsafe.Pointer
|
||||
MOV X13, (8*3)(X2) // ctxt uintptr
|
||||
MOV X8, (8*4)(X2)
|
||||
MOV X9, (8*5)(X2)
|
||||
MOV X18, (8*6)(X2)
|
||||
MOV X19, (8*7)(X2)
|
||||
MOV X20, (8*8)(X2)
|
||||
MOV X21, (8*9)(X2)
|
||||
MOV X22, (8*10)(X2)
|
||||
MOV X23, (8*11)(X2)
|
||||
MOV X24, (8*12)(X2)
|
||||
MOV X25, (8*13)(X2)
|
||||
MOV X26, (8*14)(X2)
|
||||
MOV g, (8*15)(X2)
|
||||
MOV X1, (8*16)(X2)
|
||||
MOVD F8, (8*17)(X2)
|
||||
MOVD F9, (8*18)(X2)
|
||||
MOVD F18, (8*19)(X2)
|
||||
MOVD F19, (8*20)(X2)
|
||||
MOVD F20, (8*21)(X2)
|
||||
MOVD F21, (8*22)(X2)
|
||||
MOVD F22, (8*23)(X2)
|
||||
MOVD F23, (8*24)(X2)
|
||||
MOVD F24, (8*25)(X2)
|
||||
MOVD F25, (8*26)(X2)
|
||||
MOVD F26, (8*27)(X2)
|
||||
MOVD F27, (8*28)(X2)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
CALL runtime·load_g(SB)
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
MOV (8*4)(X2), X8
|
||||
MOV (8*5)(X2), X9
|
||||
MOV (8*6)(X2), X18
|
||||
MOV (8*7)(X2), X19
|
||||
MOV (8*8)(X2), X20
|
||||
MOV (8*9)(X2), X21
|
||||
MOV (8*10)(X2), X22
|
||||
MOV (8*11)(X2), X23
|
||||
MOV (8*12)(X2), X24
|
||||
MOV (8*13)(X2), X25
|
||||
MOV (8*14)(X2), X26
|
||||
MOV (8*15)(X2), g
|
||||
MOV (8*16)(X2), X1
|
||||
MOVD (8*17)(X2), F8
|
||||
MOVD (8*18)(X2), F9
|
||||
MOVD (8*19)(X2), F18
|
||||
MOVD (8*20)(X2), F19
|
||||
MOVD (8*21)(X2), F20
|
||||
MOVD (8*22)(X2), F21
|
||||
MOVD (8*23)(X2), F22
|
||||
MOVD (8*24)(X2), F23
|
||||
MOVD (8*25)(X2), F24
|
||||
MOVD (8*26)(X2), F25
|
||||
MOVD (8*27)(X2), F26
|
||||
MOVD (8*28)(X2), F27
|
||||
ADD $(8*29), X2
|
||||
|
||||
RET
|
||||
55
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_s390x.s
generated
vendored
Normal file
55
vendor/github.com/ebitengine/purego/internal/fakecgo/asm_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
// Start with standard C stack frame layout and linkage.
|
||||
|
||||
// Save R6-R15 in the register save area of the calling function.
|
||||
STMG R6, R15, 48(R15)
|
||||
|
||||
// Allocate 96 bytes on the stack.
|
||||
MOVD $-96(R15), R15
|
||||
|
||||
// Save F8-F15 in our stack frame.
|
||||
FMOVD F8, 32(R15)
|
||||
FMOVD F9, 40(R15)
|
||||
FMOVD F10, 48(R15)
|
||||
FMOVD F11, 56(R15)
|
||||
FMOVD F12, 64(R15)
|
||||
FMOVD F13, 72(R15)
|
||||
FMOVD F14, 80(R15)
|
||||
FMOVD F15, 88(R15)
|
||||
|
||||
// Initialize Go ABI environment.
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
MOVD R2, 8(R15) // fn unsafe.Pointer
|
||||
MOVD R3, 16(R15) // a unsafe.Pointer
|
||||
|
||||
// Skip R4 = n uint32
|
||||
MOVD R5, 24(R15) // ctxt uintptr
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
FMOVD 32(R15), F8
|
||||
FMOVD 40(R15), F9
|
||||
FMOVD 48(R15), F10
|
||||
FMOVD 56(R15), F11
|
||||
FMOVD 64(R15), F12
|
||||
FMOVD 72(R15), F13
|
||||
FMOVD 80(R15), F14
|
||||
FMOVD 88(R15), F15
|
||||
|
||||
// De-allocate stack frame.
|
||||
MOVD $96(R15), R15
|
||||
|
||||
// Restore R6-R15.
|
||||
LMG 48(R15), R6, R15
|
||||
|
||||
RET
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/callbacks.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/doc.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
// Package fakecgo implements the Cgo runtime (runtime/cgo) entirely in Go.
|
||||
// This allows code that calls into C to function properly when CGO_ENABLED=0.
|
||||
|
||||
14
vendor/github.com/ebitengine/purego/internal/fakecgo/fakecgo.go
generated
vendored
Normal file
14
vendor/github.com/ebitengine/purego/internal/fakecgo/fakecgo.go
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
// setg_trampoline calls setg with the G provided
|
||||
func setg_trampoline(setg uintptr, G uintptr)
|
||||
|
||||
// call5 takes fn the C function and 5 arguments and calls the function with those arguments
|
||||
func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr
|
||||
73
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go
generated
vendored
73
vendor/github.com/ebitengine/purego/internal/fakecgo/go_darwin_amd64.go
generated
vendored
@@ -1,73 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_setstacksize(&attr, size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
|
||||
setg_func = setg
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096))
|
||||
}
|
||||
@@ -92,6 +92,8 @@ func x_cgo_init(g *G, setg uintptr) {
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/go_libinit.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
|
||||
@@ -92,6 +92,8 @@ func x_cgo_init(g *G, setg uintptr) {
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
95
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go
generated
vendored
95
vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux_amd64.go
generated
vendored
@@ -1,95 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
//go:build !cgo && (amd64 || arm64)
|
||||
|
||||
package fakecgo
|
||||
|
||||
@@ -16,7 +16,7 @@ func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
// fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
@@ -44,9 +44,20 @@ var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
var ss stack_t
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
// On NetBSD, a new thread inherits the signal stack of the
|
||||
// creating thread. That confuses minit, so we remove that
|
||||
// signal stack here before calling the regular mstart. It's
|
||||
// a bit baroque to remove a signal stack here only to add one
|
||||
// in minit, but it's a simple change that keeps NetBSD
|
||||
// working like other OS's. At this point all signals are
|
||||
// blocked, so there is no race.
|
||||
ss.ss_flags = SS_DISABLE
|
||||
sigaltstack(&ss, nil)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/go_setenv.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
|
||||
7
vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go
generated
vendored
7
vendor/github.com/ebitengine/purego/internal/fakecgo/go_util.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
@@ -28,8 +28,9 @@ func x_cgo_thread_start(arg *ThreadStart) {
|
||||
abort()
|
||||
}
|
||||
// *ts = *arg would cause a writebarrier so copy using slices
|
||||
s1 := unsafe.Slice((*uintptr)(unsafe.Pointer(ts)), unsafe.Sizeof(*ts)/8)
|
||||
s2 := unsafe.Slice((*uintptr)(unsafe.Pointer(arg)), unsafe.Sizeof(*arg)/8)
|
||||
const ptrSize = unsafe.Sizeof(uintptr(0))
|
||||
s1 := unsafe.Slice((*uintptr)(unsafe.Pointer(ts)), unsafe.Sizeof(*ts)/ptrSize)
|
||||
s2 := unsafe.Slice((*uintptr)(unsafe.Pointer(arg)), unsafe.Sizeof(*arg)/ptrSize)
|
||||
for i := range s2 {
|
||||
s1[i] = s2[i]
|
||||
}
|
||||
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/iscgo.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
// The runtime package contains an uninitialized definition
|
||||
// for runtime·iscgo. Override it to tell the runtime we're here.
|
||||
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
|
||||
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go
generated
vendored
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_darwin.go
generated
vendored
@@ -20,3 +20,7 @@ var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{sig: 0x3CB0B1BB}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{sig: 0x32AAABA7}
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go
generated
vendored
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_freebsd.go
generated
vendored
@@ -14,3 +14,7 @@ var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t(0)
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0)
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go
generated
vendored
4
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_linux.go
generated
vendored
@@ -14,3 +14,7 @@ var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{}
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
|
||||
26
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go
generated
vendored
Normal file
26
vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t uintptr
|
||||
pthread_mutex_t uintptr
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t(0)
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0)
|
||||
)
|
||||
|
||||
// Source: https://github.com/NetBSD/src/blob/613e27c65223fd2283b6ed679da1197e12f50e27/sys/compat/linux/arch/m68k/linux_signal.h#L133
|
||||
type stack_t struct {
|
||||
ss_sp uintptr
|
||||
ss_flags int32
|
||||
ss_size uintptr
|
||||
}
|
||||
|
||||
// Source: https://github.com/NetBSD/src/blob/613e27c65223fd2283b6ed679da1197e12f50e27/sys/sys/signal.h#L261
|
||||
const SS_DISABLE = 0x004
|
||||
23
vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go
generated
vendored
Normal file
23
vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build netbsd
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
// Supply environ and __progname, because we don't
|
||||
// link against the standard NetBSD crt0.o and the
|
||||
// libc dynamic library needs them.
|
||||
|
||||
//go:linkname _environ environ
|
||||
//go:linkname _progname __progname
|
||||
//go:linkname ___ps_strings __ps_strings
|
||||
|
||||
var (
|
||||
_environ uintptr
|
||||
_progname uintptr
|
||||
___ps_strings uintptr
|
||||
)
|
||||
2
vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go
generated
vendored
2
vendor/github.com/ebitengine/purego/internal/fakecgo/setenv.go
generated
vendored
@@ -2,7 +2,7 @@
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
|
||||
107
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_386.s
generated
vendored
Normal file
107
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_386.s
generated
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (freebsd || linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the gcc ABI to Go ABI0 and then call into the Go equivalent functions.
|
||||
// On i386, both GCC and Go use stack-based calling conventions.
|
||||
//
|
||||
// When C calls a function, the stack looks like:
|
||||
// 0(SP) = return address
|
||||
// 4(SP) = arg1
|
||||
// 8(SP) = arg2
|
||||
// ...
|
||||
//
|
||||
// When we declare a Go function with frame size $N-0, Go's prologue
|
||||
// effectively does SUB $N, SP, so the C arguments shift up by N bytes:
|
||||
// N+0(SP) = return address
|
||||
// N+4(SP) = arg1
|
||||
// N+8(SP) = arg2
|
||||
//
|
||||
// Go ABI0 on 386 expects arguments starting at 0(FP) which equals N+4(SP)
|
||||
// after the prologue (where N is the local frame size).
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $8-0
|
||||
// C args at 12(SP) and 16(SP) after frame setup (8 bytes local + 4 bytes ret addr)
|
||||
// Go function expects args at 0(SP) and 4(SP) in local frame
|
||||
MOVL 12(SP), AX // first C arg
|
||||
MOVL 16(SP), BX // second C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL BX, 4(SP) // Go arg 2
|
||||
MOVL ·x_cgo_init_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $4-0
|
||||
// C args at 8(SP) after frame setup (4 bytes local + 4 bytes ret addr)
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_thread_start_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_setenv_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_unsetenv_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
// This is called from Go, so args are at normal FP positions
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $4-8
|
||||
MOVL g+4(FP), AX
|
||||
MOVL setg+0(FP), BX
|
||||
|
||||
// setg expects g in 0(SP)
|
||||
MOVL AX, 0(SP)
|
||||
CALL BX
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·threadentry_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $20-28
|
||||
MOVL fn+0(FP), AX
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL a4+16(FP), SI
|
||||
MOVL a5+20(FP), DI
|
||||
|
||||
// Place arguments on local stack frame for C calling convention
|
||||
MOVL BX, 0(SP) // a1
|
||||
MOVL CX, 4(SP) // a2
|
||||
MOVL DX, 8(SP) // a3
|
||||
MOVL SI, 12(SP) // a4
|
||||
MOVL DI, 16(SP) // a5
|
||||
CALL AX
|
||||
MOVL AX, r1+24(FP)
|
||||
RET
|
||||
63
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s
generated
vendored
63
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s
generated
vendored
@@ -7,12 +7,6 @@
|
||||
trampoline for emulating required C functions for cgo in go (see cgo.go)
|
||||
(we convert cdecl calling convention to go and vice-versa)
|
||||
|
||||
Since we're called from go and call into C we can cheat a bit with the calling conventions:
|
||||
- in go all the registers are caller saved
|
||||
- in C we have a couple of callee saved registers
|
||||
|
||||
=> we can use BX, R12, R13, R14, R15 instead of the stack
|
||||
|
||||
C Calling convention cdecl used here (we only need integer args):
|
||||
1. arg: DI
|
||||
2. arg: SI
|
||||
@@ -22,66 +16,75 @@ C Calling convention cdecl used here (we only need integer args):
|
||||
6. arg: R9
|
||||
We don't need floats with these functions -> AX=0
|
||||
return value will be in AX
|
||||
temporary register is R11
|
||||
*/
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_amd64.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOVQ DI, AX
|
||||
MOVQ SI, BX
|
||||
MOVQ ·x_cgo_init_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
MOVQ ·x_cgo_init_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_thread_start_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
MOVQ ·x_cgo_thread_start_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_setenv_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
MOVQ ·x_cgo_setenv_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_unsetenv_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
MOVQ ·x_cgo_unsetenv_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
JMP ·x_cgo_notify_runtime_init_done(SB)
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
JMP ·x_cgo_bindm(SB)
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVQ G+8(FP), DI
|
||||
MOVQ setg+0(FP), BX
|
||||
MOVQ setg+0(FP), R11
|
||||
XORL AX, AX
|
||||
CALL BX
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $16
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0
|
||||
// See crosscall2.
|
||||
PUSH_REGS_HOST_TO_ABI0()
|
||||
|
||||
// X15 is designated by Go as a fixed zero register.
|
||||
// Calling directly into ABIInternal, ensure it is zero.
|
||||
PXOR X15, X15
|
||||
|
||||
MOVQ DI, AX
|
||||
MOVQ ·threadentry_call(SB), DX
|
||||
MOVQ (DX), CX
|
||||
CALL CX
|
||||
MOVQ ·threadentry_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
|
||||
POP_REGS_HOST_TO_ABI0()
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-56
|
||||
MOVQ fn+0(FP), BX
|
||||
MOVQ fn+0(FP), R11
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
@@ -95,7 +98,7 @@ TEXT ·call5(SB), NOSPLIT, $0-56
|
||||
SUBQ $16, SP // allocate space for alignment
|
||||
ANDQ $-16, SP // align on 16 bytes for SSE
|
||||
|
||||
CALL BX
|
||||
CALL R11
|
||||
|
||||
MOVQ BP, SP // get SP back
|
||||
POPQ BP // restore BP
|
||||
|
||||
81
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm.s
generated
vendored
Normal file
81
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm.s
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (freebsd || linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the gcc ABI to Go ABI0 and then call into the Go equivalent functions.
|
||||
// On ARM32, Go ABI0 uses stack-based calling convention.
|
||||
// Arguments are placed on the stack starting at 4(SP) after the prologue.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW R1, 8(R13)
|
||||
MOVW ·x_cgo_init_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_thread_start_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_setenv_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_unsetenv_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-8
|
||||
MOVW G+4(FP), R0
|
||||
MOVW setg+0(FP), R12
|
||||
BL (R12)
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $8-0
|
||||
// See crosscall2.
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·threadentry_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $8-28
|
||||
MOVW fn+0(FP), R12
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
MOVW a4+16(FP), R3
|
||||
MOVW a5+20(FP), R4
|
||||
|
||||
// Store 5th arg below SP (in local frame area)
|
||||
MOVW R4, arg5-8(SP)
|
||||
|
||||
// Align SP to 8 bytes for call (required by ARM AAPCS)
|
||||
SUB $8, R13
|
||||
CALL (R12)
|
||||
ADD $8, R13
|
||||
MOVW R0, r1+24(FP)
|
||||
RET
|
||||
66
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s
generated
vendored
66
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s
generated
vendored
@@ -5,36 +5,34 @@
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_arm64.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
// These trampolines map the gcc ABI to Go ABIInternal and then calls into the Go equivalent functions.
|
||||
// Note that C arguments are passed in R0-R7, which matches Go ABIInternal for the first eight arguments.
|
||||
// R9 is used as a temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD R1, 16(RSP)
|
||||
MOVD ·x_cgo_init_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD ·x_cgo_init_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_thread_start_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD ·x_cgo_thread_start_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_setenv_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD ·x_cgo_setenv_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
@@ -48,25 +46,39 @@ TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVD G+8(FP), R0
|
||||
MOVD setg+0(FP), R1
|
||||
CALL R1
|
||||
MOVD setg+0(FP), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD R0, 8(RSP)
|
||||
MOVD ·threadentry_call(SB), R26
|
||||
MOVD (R26), R2
|
||||
CALL (R2)
|
||||
MOVD $0, R0 // TODO: get the return value from threadentry
|
||||
// See crosscall2.
|
||||
SUB $(8*24), RSP
|
||||
STP (R0, R1), (8*1)(RSP)
|
||||
MOVD R3, (8*3)(RSP)
|
||||
|
||||
SAVE_R19_TO_R28(8*4)
|
||||
SAVE_F8_TO_F15(8*14)
|
||||
STP (R29, R30), (8*22)(RSP)
|
||||
|
||||
MOVD ·threadentry_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
MOVD $0, R0 // TODO: get the return value from threadentry
|
||||
|
||||
RESTORE_R19_TO_R28(8*4)
|
||||
RESTORE_F8_TO_F15(8*14)
|
||||
LDP (8*22)(RSP), (R29, R30)
|
||||
|
||||
ADD $(8*24), RSP
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-0
|
||||
MOVD fn+0(FP), R6
|
||||
MOVD fn+0(FP), R9
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
CALL R6
|
||||
CALL R9
|
||||
MOVD R0, ret+48(FP)
|
||||
RET
|
||||
|
||||
88
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s
generated
vendored
Normal file
88
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_loong64.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
// R23 is used as temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOVV R4, 8(R3)
|
||||
MOVV R5, 16(R3)
|
||||
MOVV ·x_cgo_init_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_thread_start_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_setenv_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_unsetenv_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0
|
||||
MOVV G+8(FP), R4
|
||||
MOVV setg+0(FP), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0
|
||||
// See crosscall2.
|
||||
ADDV $(-23*8), R3
|
||||
MOVV R4, (1*8)(R3) // fn unsafe.Pointer
|
||||
MOVV R5, (2*8)(R3) // a unsafe.Pointer
|
||||
MOVV R7, (3*8)(R3) // ctxt uintptr
|
||||
|
||||
SAVE_R22_TO_R31((4*8))
|
||||
SAVE_F24_TO_F31((14*8))
|
||||
MOVV R1, (22*8)(R3)
|
||||
|
||||
MOVV ·threadentry_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
|
||||
RESTORE_R22_TO_R31((4*8))
|
||||
RESTORE_F24_TO_F31((14*8))
|
||||
MOVV (22*8)(R3), R1
|
||||
|
||||
ADDV $(23*8), R3
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-0
|
||||
MOVV fn+0(FP), R23
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV a4+32(FP), R7
|
||||
MOVV a5+40(FP), R8
|
||||
CALL (R23)
|
||||
MOVV R4, ret+48(FP)
|
||||
RET
|
||||
227
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_ppc64le.s
generated
vendored
Normal file
227
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_ppc64le.s
generated
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the C ABI to Go ABI and call into the Go equivalent functions.
|
||||
//
|
||||
// PPC64LE ELFv2 ABI stack frame layout:
|
||||
// 0(R1) = backchain (pointer to caller's frame)
|
||||
// 8(R1) = CR save area
|
||||
// 16(R1) = LR save area
|
||||
// 24(R1) = reserved
|
||||
// 32(R1) = parameter save area (minimum 64 bytes for 8 args)
|
||||
//
|
||||
// Two patterns are used depending on call direction:
|
||||
//
|
||||
// C→Go trampolines: The C caller already provides a 32-byte linkage area.
|
||||
// Save LR/CR into caller's frame at 16(R1)/8(R1) BEFORE allocating,
|
||||
// then use MOVDU to allocate and set backchain atomically.
|
||||
//
|
||||
// Go→C trampolines: Go callers don't provide ELFv2 linkage area.
|
||||
// Allocate frame first with MOVDU, then save LR/CR into OUR frame.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
// R3, R4 already have the arguments
|
||||
MOVD ·x_cgo_init_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_thread_start_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
// void (*_cgo_setenv)(char**)
|
||||
// C arg: R3 = pointer to env
|
||||
// This is C→Go: caller is C ABI.
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_setenv_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT|NOFRAME, $0-16
|
||||
// Save LR, CR, and R31 to non-volatile registers (C ABI preserves R14-R31)
|
||||
MOVD LR, R20
|
||||
MOVW CR, R21
|
||||
MOVD R31, R22 // save R31 because load_g clobbers it
|
||||
|
||||
// Load arguments from Go stack
|
||||
MOVD 32(R1), R12 // setg function pointer
|
||||
MOVD 40(R1), R3 // g pointer → first C arg
|
||||
|
||||
// Allocate ELFv2 frame for the C callee (32 bytes minimum)
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
// Call setg_gcc which stores g to TLS
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
// setg_gcc stored g to TLS but restored old g in R30.
|
||||
// Call load_g to reload g from TLS into R30.
|
||||
// Note: load_g clobbers R31
|
||||
CALL runtime·load_g(SB)
|
||||
|
||||
// Deallocate frame
|
||||
ADD $32, R1
|
||||
|
||||
// Clear R0 before returning to Go code.
|
||||
// Go uses R0 as a constant 0 for things like "std r0,X(r1)" to zero stack locations.
|
||||
// C/assembly functions may leave garbage in R0.
|
||||
XOR R0, R0, R0
|
||||
|
||||
// Restore LR, CR, and R31 from non-volatile registers
|
||||
MOVD R22, R31 // restore R31
|
||||
MOVD R20, LR
|
||||
MOVW R21, CR
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·threadentry_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT|NOFRAME, $0-56
|
||||
MOVD LR, R20
|
||||
MOVW CR, R21
|
||||
|
||||
// Load arguments from Go stack into C argument registers
|
||||
// Go placed args at 32(R1), 40(R1), etc.
|
||||
MOVD 32(R1), R12 // fn
|
||||
MOVD 40(R1), R3 // a1 → first C arg
|
||||
MOVD 48(R1), R4 // a2 → second C arg
|
||||
MOVD 56(R1), R5 // a3 → third C arg
|
||||
MOVD 64(R1), R6 // a4 → fourth C arg
|
||||
MOVD 72(R1), R7 // a5 → fifth C arg
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
// Store return value
|
||||
// After MOVDU -32, original 80(R1) is now at 80+32=112(R1)
|
||||
MOVD R3, (80+32)(R1)
|
||||
|
||||
// Deallocate frame
|
||||
ADD $32, R1
|
||||
|
||||
// Clear R0 before returning to Go code.
|
||||
// Go uses R0 as a constant 0 register for things like "std r0,X(r1)"
|
||||
// to zero stack locations. C functions may leave garbage in R0.
|
||||
XOR R0, R0, R0
|
||||
|
||||
// Restore LR/CR from non-volatile registers
|
||||
MOVD R20, LR
|
||||
MOVW R21, CR
|
||||
RET
|
||||
72
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_riscv64.s
generated
vendored
Normal file
72
vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_riscv64.s
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
// X5 is used as temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOV X10, 8(SP)
|
||||
MOV X11, 16(SP)
|
||||
MOV ·x_cgo_init_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_thread_start_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_setenv_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_unsetenv_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0
|
||||
MOV gp+8(FP), X10
|
||||
MOV setg+0(FP), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $16
|
||||
MOV X10, 8(SP)
|
||||
MOV ·threadentry_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-48
|
||||
MOV fn+0(FP), X5
|
||||
MOV a1+8(FP), X10
|
||||
MOV a2+16(FP), X11
|
||||
MOV a3+24(FP), X12
|
||||
MOV a4+32(FP), X13
|
||||
MOV a5+40(FP), X14
|
||||
CALL X5
|
||||
MOV X10, ret+48(FP)
|
||||
RET
|
||||
@@ -3,7 +3,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
@@ -12,12 +12,6 @@ import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// setg_trampoline calls setg with the G provided
|
||||
func setg_trampoline(setg uintptr, G uintptr)
|
||||
|
||||
// call5 takes fn the C function and 5 arguments and calls the function with those arguments
|
||||
func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func malloc(size uintptr) unsafe.Pointer {
|
||||
@@ -86,36 +80,6 @@ func pthread_sigmask(how sighow, ign *sigset_t, oset *sigset_t) int32 {
|
||||
return int32(call5(pthread_sigmaskABI0, uintptr(how), uintptr(unsafe.Pointer(ign)), uintptr(unsafe.Pointer(oset)), 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_self() pthread_t {
|
||||
return pthread_t(call5(pthread_selfABI0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_get_stacksize_np(thread pthread_t) size_t {
|
||||
return size_t(call5(pthread_get_stacksize_npABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_setstacksize(attr *pthread_attr_t, size size_t) int32 {
|
||||
return int32(call5(pthread_attr_setstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(size), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_mutex_lock(mutex *pthread_mutex_t) int32 {
|
||||
@@ -184,26 +148,6 @@ var pthread_detachABI0 = uintptr(unsafe.Pointer(&_pthread_detach))
|
||||
var _pthread_sigmask uint8
|
||||
var pthread_sigmaskABI0 = uintptr(unsafe.Pointer(&_pthread_sigmask))
|
||||
|
||||
//go:linkname _pthread_self _pthread_self
|
||||
var _pthread_self uint8
|
||||
var pthread_selfABI0 = uintptr(unsafe.Pointer(&_pthread_self))
|
||||
|
||||
//go:linkname _pthread_get_stacksize_np _pthread_get_stacksize_np
|
||||
var _pthread_get_stacksize_np uint8
|
||||
var pthread_get_stacksize_npABI0 = uintptr(unsafe.Pointer(&_pthread_get_stacksize_np))
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize
|
||||
var _pthread_attr_setstacksize uint8
|
||||
var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
|
||||
//go:linkname _pthread_mutex_lock _pthread_mutex_lock
|
||||
var _pthread_mutex_lock uint8
|
||||
var pthread_mutex_lockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_lock))
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_free free "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "/usr/lib/libSystem.B.dylib"
|
||||
@@ -18,12 +20,40 @@ package fakecgo
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_self() pthread_t {
|
||||
return pthread_t(call5(pthread_selfABI0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_get_stacksize_np(thread pthread_t) size_t {
|
||||
return size_t(call5(pthread_get_stacksize_npABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_setstacksize(attr *pthread_attr_t, size size_t) int32 {
|
||||
return int32(call5(pthread_attr_setstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(size), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_self _pthread_self
|
||||
var _pthread_self uint8
|
||||
var pthread_selfABI0 = uintptr(unsafe.Pointer(&_pthread_self))
|
||||
|
||||
//go:linkname _pthread_get_stacksize_np _pthread_get_stacksize_np
|
||||
var _pthread_get_stacksize_np uint8
|
||||
var pthread_get_stacksize_npABI0 = uintptr(unsafe.Pointer(&_pthread_get_stacksize_np))
|
||||
|
||||
//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize
|
||||
var _pthread_attr_setstacksize uint8
|
||||
var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize))
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.7"
|
||||
@@ -18,12 +20,29 @@ package fakecgo
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.6"
|
||||
@@ -18,12 +20,29 @@ package fakecgo
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so.0"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
59
vendor/github.com/ebitengine/purego/internal/fakecgo/zsymbols_netbsd.go
generated
vendored
Normal file
59
vendor/github.com/ebitengine/purego/internal/fakecgo/zsymbols_netbsd.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so"
|
||||
//go:cgo_import_dynamic purego_sigaltstack sigaltstack "libc.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func sigaltstack(ss *stack_t, old_ss *stack_t) int32 {
|
||||
return int32(call5(sigaltstackABI0, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(old_ss)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _sigaltstack _sigaltstack
|
||||
var _sigaltstack uint8
|
||||
var sigaltstackABI0 = uintptr(unsafe.Pointer(&_sigaltstack))
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
19
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_darwin.s
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_darwin.s
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_self(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_self(SB)
|
||||
|
||||
TEXT _pthread_get_stacksize_np(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_get_stacksize_np(SB)
|
||||
|
||||
TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_setstacksize(SB)
|
||||
16
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_freebsd.s
generated
vendored
Normal file
16
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_freebsd.s
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
16
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_linux.s
generated
vendored
Normal file
16
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_linux.s
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
19
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_netbsd.s
generated
vendored
Normal file
19
vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_netbsd.s
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _sigaltstack(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_sigaltstack(SB)
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
@@ -3,88 +3,53 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions on darwin arm64
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _malloc(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_malloc(SB)
|
||||
RET
|
||||
|
||||
TEXT _free(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_free(SB)
|
||||
RET
|
||||
|
||||
TEXT _setenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_setenv(SB)
|
||||
RET
|
||||
|
||||
TEXT _unsetenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_unsetenv(SB)
|
||||
RET
|
||||
|
||||
TEXT _sigfillset(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_sigfillset(SB)
|
||||
RET
|
||||
|
||||
TEXT _nanosleep(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_nanosleep(SB)
|
||||
RET
|
||||
|
||||
TEXT _abort(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_abort(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_init(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_init(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_create(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_create(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_detach(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_detach(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_sigmask(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_sigmask(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_self(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_self(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_get_stacksize_np(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_get_stacksize_np(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_setstacksize(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_mutex_lock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_lock(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_mutex_unlock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_unlock(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_cond_broadcast(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_cond_broadcast(SB)
|
||||
RET
|
||||
|
||||
TEXT _pthread_setspecific(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_setspecific(SB)
|
||||
RET
|
||||
15
vendor/github.com/ebitengine/purego/internal/xreflect/reflect_go124.go
generated
vendored
Normal file
15
vendor/github.com/ebitengine/purego/internal/xreflect/reflect_go124.go
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !go1.25
|
||||
|
||||
package xreflect
|
||||
|
||||
import "reflect"
|
||||
|
||||
// TODO: remove this and use Go 1.25's reflect.TypeAssert when minimum go.mod version is 1.25
|
||||
|
||||
func TypeAssert[T any](v reflect.Value) (T, bool) {
|
||||
v2, ok := v.Interface().(T)
|
||||
return v2, ok
|
||||
}
|
||||
12
vendor/github.com/ebitengine/purego/internal/xreflect/reflect_go125.go
generated
vendored
Normal file
12
vendor/github.com/ebitengine/purego/internal/xreflect/reflect_go125.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build go1.25
|
||||
|
||||
package xreflect
|
||||
|
||||
import "reflect"
|
||||
|
||||
func TypeAssert[T any](v reflect.Value) (T, bool) {
|
||||
return reflect.TypeAssert[T](v)
|
||||
}
|
||||
2
vendor/github.com/ebitengine/purego/nocgo.go
generated
vendored
2
vendor/github.com/ebitengine/purego/nocgo.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package purego
|
||||
|
||||
|
||||
41
vendor/github.com/ebitengine/purego/struct_386.go
generated
vendored
Normal file
41
vendor/github.com/ebitengine/purego/struct_386.go
generated
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import "reflect"
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
|
||||
panic("purego: struct arguments are not supported")
|
||||
}
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
|
||||
panic("purego: struct returns are not supported")
|
||||
}
|
||||
|
||||
func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
panic("purego: placeRegisters not implemented on 386")
|
||||
}
|
||||
|
||||
// shouldBundleStackArgs always returns false on 386
|
||||
// since C-style stack argument bundling is only needed on Darwin ARM64.
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// structFitsInRegisters is not used on 386.
|
||||
func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
|
||||
panic("purego: structFitsInRegisters should not be called on 386")
|
||||
}
|
||||
|
||||
// collectStackArgs is not used on 386.
|
||||
func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
|
||||
keepAlive []any, addInt, addFloat, addStack func(uintptr),
|
||||
pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
|
||||
panic("purego: collectStackArgs should not be called on 386")
|
||||
}
|
||||
|
||||
// bundleStackArgs is not used on 386.
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("purego: bundleStackArgs should not be called on 386")
|
||||
}
|
||||
76
vendor/github.com/ebitengine/purego/struct_amd64.go
generated
vendored
76
vendor/github.com/ebitengine/purego/struct_amd64.go
generated
vendored
@@ -85,7 +85,7 @@ const (
|
||||
_MEMORY = 0b1111
|
||||
)
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []interface{}) []interface{} {
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
|
||||
if v.Type().Size() == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
@@ -120,7 +120,7 @@ func postMerger(t reflect.Type) (passInMemory bool) {
|
||||
if t.Size() <= 2*8 {
|
||||
return false
|
||||
}
|
||||
return true // Go does not have an SSE/SEEUP type so this is always true
|
||||
return true // Go does not have an SSE/SSEUP type so this is always true
|
||||
}
|
||||
|
||||
func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) (ok bool) {
|
||||
@@ -165,13 +165,14 @@ func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintp
|
||||
place(f)
|
||||
case reflect.Bool:
|
||||
if f.Bool() {
|
||||
val |= 1
|
||||
val |= 1 << shift
|
||||
}
|
||||
shift += 8
|
||||
class |= _INTEGER
|
||||
case reflect.Pointer:
|
||||
ok = false
|
||||
return
|
||||
case reflect.Pointer, reflect.UnsafePointer:
|
||||
val = uint64(f.Pointer())
|
||||
shift = 64
|
||||
class = _INTEGER
|
||||
case reflect.Int8:
|
||||
val |= uint64(f.Int()&0xFF) << shift
|
||||
shift += 8
|
||||
@@ -200,7 +201,7 @@ func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintp
|
||||
val |= f.Uint() << shift
|
||||
shift += 32
|
||||
class |= _INTEGER
|
||||
case reflect.Uint64, reflect.Uint:
|
||||
case reflect.Uint64, reflect.Uint, reflect.Uintptr:
|
||||
val = f.Uint()
|
||||
shift = 64
|
||||
class = _INTEGER
|
||||
@@ -238,23 +239,48 @@ func tryPlaceRegister(v reflect.Value, addFloat func(uintptr), addInt func(uintp
|
||||
}
|
||||
|
||||
func placeStack(v reflect.Value, addStack func(uintptr)) {
|
||||
for i := 0; i < v.Type().NumField(); i++ {
|
||||
f := v.Field(i)
|
||||
switch f.Kind() {
|
||||
case reflect.Pointer:
|
||||
addStack(f.Pointer())
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
addStack(uintptr(f.Int()))
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
addStack(uintptr(f.Uint()))
|
||||
case reflect.Float32:
|
||||
addStack(uintptr(math.Float32bits(float32(f.Float()))))
|
||||
case reflect.Float64:
|
||||
addStack(uintptr(math.Float64bits(f.Float())))
|
||||
case reflect.Struct:
|
||||
placeStack(f, addStack)
|
||||
default:
|
||||
panic("purego: unsupported kind " + f.Kind().String())
|
||||
}
|
||||
// Copy the struct as a contiguous block of memory in eightbyte (8-byte)
|
||||
// chunks. The x86-64 ABI requires structs passed on the stack to be
|
||||
// laid out exactly as in memory, including padding and field packing
|
||||
// within eightbytes. Decomposing field-by-field would place each field
|
||||
// as a separate stack slot, breaking structs with mixed-type fields
|
||||
// that share an eightbyte (e.g. int32 + float32).
|
||||
if !v.CanAddr() {
|
||||
tmp := reflect.New(v.Type()).Elem()
|
||||
tmp.Set(v)
|
||||
v = tmp
|
||||
}
|
||||
ptr := v.Addr().UnsafePointer()
|
||||
size := v.Type().Size()
|
||||
for off := uintptr(0); off < size; off += 8 {
|
||||
chunk := *(*uintptr)(unsafe.Add(ptr, off))
|
||||
addStack(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
panic("purego: placeRegisters not implemented on amd64")
|
||||
}
|
||||
|
||||
// shouldBundleStackArgs always returns false on non-Darwin platforms
|
||||
// since C-style stack argument bundling is only needed on Darwin ARM64.
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// structFitsInRegisters is not used on amd64.
|
||||
func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
|
||||
panic("purego: structFitsInRegisters should not be called on amd64")
|
||||
}
|
||||
|
||||
// collectStackArgs is not used on amd64.
|
||||
func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
|
||||
keepAlive []any, addInt, addFloat, addStack func(uintptr),
|
||||
pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
|
||||
panic("purego: collectStackArgs should not be called on amd64")
|
||||
}
|
||||
|
||||
// bundleStackArgs is not used on amd64.
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("purego: bundleStackArgs should not be called on amd64")
|
||||
}
|
||||
|
||||
85
vendor/github.com/ebitengine/purego/struct_arm.go
generated
vendored
Normal file
85
vendor/github.com/ebitengine/purego/struct_arm.go
generated
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
|
||||
size := v.Type().Size()
|
||||
if size == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// TODO: ARM EABI: small structs are passed in registers or on stack
|
||||
// For simplicity, pass by pointer for now
|
||||
ptr := v.Addr().UnsafePointer()
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
if *numInts < 4 {
|
||||
addInt(uintptr(ptr))
|
||||
*numInts++
|
||||
} else {
|
||||
addStack(uintptr(ptr))
|
||||
*numStack++
|
||||
}
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
|
||||
outSize := outType.Size()
|
||||
if outSize == 0 {
|
||||
return reflect.New(outType).Elem()
|
||||
}
|
||||
if outSize <= 4 {
|
||||
// Fits in one register
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&struct{ a uintptr }{syscall.a1})).Elem()
|
||||
}
|
||||
if outSize <= 8 {
|
||||
// Fits in two registers
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&struct{ a, b uintptr }{syscall.a1, syscall.a2})).Elem()
|
||||
}
|
||||
// Larger structs returned via pointer in a1
|
||||
return reflect.NewAt(outType, *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))).Elem()
|
||||
}
|
||||
|
||||
func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
// TODO: For ARM32, just pass the struct data directly
|
||||
// This is a simplified implementation
|
||||
size := v.Type().Size()
|
||||
if size == 0 {
|
||||
return
|
||||
}
|
||||
ptr := unsafe.Pointer(v.UnsafeAddr())
|
||||
if size <= 4 {
|
||||
addInt(*(*uintptr)(ptr))
|
||||
} else if size <= 8 {
|
||||
addInt(*(*uintptr)(ptr))
|
||||
addInt(*(*uintptr)(unsafe.Add(ptr, 4)))
|
||||
}
|
||||
}
|
||||
|
||||
// shouldBundleStackArgs always returns false on arm
|
||||
// since C-style stack argument bundling is only needed on Darwin ARM64.
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// structFitsInRegisters is not used on arm.
|
||||
func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
|
||||
panic("purego: structFitsInRegisters should not be called on arm")
|
||||
}
|
||||
|
||||
// collectStackArgs is not used on arm.
|
||||
func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
|
||||
keepAlive []any, addInt, addFloat, addStack func(uintptr),
|
||||
pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
|
||||
panic("purego: collectStackArgs should not be called on arm")
|
||||
}
|
||||
|
||||
// bundleStackArgs is not used on arm.
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("purego: bundleStackArgs should not be called on arm")
|
||||
}
|
||||
289
vendor/github.com/ebitengine/purego/struct_arm64.go
generated
vendored
289
vendor/github.com/ebitengine/purego/struct_arm64.go
generated
vendored
@@ -6,7 +6,12 @@ package purego
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
stdstrings "strings"
|
||||
"unsafe"
|
||||
|
||||
"github.com/ebitengine/purego/internal/strings"
|
||||
)
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
|
||||
@@ -65,7 +70,7 @@ const (
|
||||
_INT = 0b11
|
||||
)
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []interface{}) []interface{} {
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
|
||||
if v.Type().Size() == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
@@ -73,8 +78,8 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl
|
||||
if hva, hfa, size := isHVA(v.Type()), isHFA(v.Type()), v.Type().Size(); hva || hfa || size <= 16 {
|
||||
// if this doesn't fit entirely in registers then
|
||||
// each element goes onto the stack
|
||||
if hfa && *numFloats+v.NumField() > numOfFloats {
|
||||
*numFloats = numOfFloats
|
||||
if hfa && *numFloats+v.NumField() > numOfFloatRegisters() {
|
||||
*numFloats = numOfFloatRegisters()
|
||||
} else if hva && *numInts+v.NumField() > numOfIntegerRegisters() {
|
||||
*numInts = numOfIntegerRegisters()
|
||||
}
|
||||
@@ -87,6 +92,14 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl
|
||||
}
|
||||
|
||||
func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
if runtime.GOOS == "darwin" {
|
||||
placeRegistersDarwin(v, addFloat, addInt)
|
||||
return
|
||||
}
|
||||
placeRegistersArm64(v, addFloat, addInt)
|
||||
}
|
||||
|
||||
func placeRegistersArm64(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
var val uint64
|
||||
var shift byte
|
||||
var flushed bool
|
||||
@@ -107,6 +120,8 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
} else {
|
||||
f = v.Index(k)
|
||||
}
|
||||
align := byte(f.Type().Align()*8 - 1)
|
||||
shift = (shift + align) &^ align
|
||||
if shift >= 64 {
|
||||
shift = 0
|
||||
flushed = true
|
||||
@@ -115,13 +130,15 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
} else {
|
||||
addInt(uintptr(val))
|
||||
}
|
||||
val = 0
|
||||
class = _NO_CLASS
|
||||
}
|
||||
switch f.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
place(f)
|
||||
case reflect.Bool:
|
||||
if f.Bool() {
|
||||
val |= 1
|
||||
val |= 1 << shift
|
||||
}
|
||||
shift += 8
|
||||
class |= _INT
|
||||
@@ -137,10 +154,11 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
val |= f.Uint() << shift
|
||||
shift += 32
|
||||
class |= _INT
|
||||
case reflect.Uint64:
|
||||
case reflect.Uint64, reflect.Uint, reflect.Uintptr:
|
||||
addInt(uintptr(f.Uint()))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Int8:
|
||||
val |= uint64(f.Int()&0xFF) << shift
|
||||
shift += 8
|
||||
@@ -153,10 +171,11 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
val |= uint64(f.Int()&0xFFFF_FFFF) << shift
|
||||
shift += 32
|
||||
class |= _INT
|
||||
case reflect.Int64:
|
||||
case reflect.Int64, reflect.Int:
|
||||
addInt(uintptr(f.Int()))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Float32:
|
||||
if class == _FLOAT {
|
||||
addFloat(uintptr(val))
|
||||
@@ -170,6 +189,12 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
addFloat(uintptr(math.Float64bits(float64(f.Float()))))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Ptr, reflect.UnsafePointer:
|
||||
addInt(f.Pointer())
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Array:
|
||||
place(f)
|
||||
default:
|
||||
@@ -187,7 +212,7 @@ func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr
|
||||
}
|
||||
}
|
||||
|
||||
func placeStack(v reflect.Value, keepAlive []interface{}, addInt func(uintptr)) []interface{} {
|
||||
func placeStack(v reflect.Value, keepAlive []any, addInt func(uintptr)) []any {
|
||||
// Struct is too big to be placed in registers.
|
||||
// Copy to heap and place the pointer in register
|
||||
ptrStruct := reflect.New(v.Type())
|
||||
@@ -272,3 +297,253 @@ func isHVA(t reflect.Type) bool {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// copyStruct8ByteChunks copies struct memory in 8-byte chunks to the provided callback.
|
||||
// This is used for Darwin ARM64's byte-level packing of non-HFA/HVA structs.
|
||||
func copyStruct8ByteChunks(ptr unsafe.Pointer, size uintptr, addChunk func(uintptr)) {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: should only be called on darwin")
|
||||
}
|
||||
for offset := uintptr(0); offset < size; offset += 8 {
|
||||
var chunk uintptr
|
||||
remaining := size - offset
|
||||
if remaining >= 8 {
|
||||
chunk = *(*uintptr)(unsafe.Add(ptr, offset))
|
||||
} else {
|
||||
// Read byte-by-byte to avoid reading beyond allocation
|
||||
for i := uintptr(0); i < remaining; i++ {
|
||||
b := *(*byte)(unsafe.Add(ptr, offset+i))
|
||||
chunk |= uintptr(b) << (i * 8)
|
||||
}
|
||||
}
|
||||
addChunk(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
// placeRegisters implements Darwin ARM64 calling convention for struct arguments.
|
||||
//
|
||||
// For HFA/HVA structs, each element must go in a separate register (or stack slot for elements
|
||||
// that don't fit in registers). We use placeRegistersArm64 for this.
|
||||
//
|
||||
// For non-HFA/HVA structs, Darwin uses byte-level packing. We copy the struct memory in
|
||||
// 8-byte chunks, which works correctly for both register and stack placement.
|
||||
func placeRegistersDarwin(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: placeRegistersDarwin should only be called on darwin")
|
||||
}
|
||||
// Check if this is an HFA/HVA
|
||||
hfa := isHFA(v.Type())
|
||||
hva := isHVA(v.Type())
|
||||
|
||||
// For HFA/HVA structs, use the standard ARM64 logic which places each element separately
|
||||
if hfa || hva {
|
||||
placeRegistersArm64(v, addFloat, addInt)
|
||||
return
|
||||
}
|
||||
|
||||
// For non-HFA/HVA structs, use byte-level copying
|
||||
// If the value is not addressable, create an addressable copy
|
||||
if !v.CanAddr() {
|
||||
addressable := reflect.New(v.Type()).Elem()
|
||||
addressable.Set(v)
|
||||
v = addressable
|
||||
}
|
||||
ptr := unsafe.Pointer(v.Addr().Pointer())
|
||||
size := v.Type().Size()
|
||||
copyStruct8ByteChunks(ptr, size, addInt)
|
||||
}
|
||||
|
||||
// shouldBundleStackArgs determines if we need to start C-style packing for
|
||||
// Darwin ARM64 stack arguments. This happens when registers are exhausted.
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
if runtime.GOOS != "darwin" {
|
||||
return false
|
||||
}
|
||||
|
||||
kind := v.Kind()
|
||||
isFloat := kind == reflect.Float32 || kind == reflect.Float64
|
||||
isInt := !isFloat && kind != reflect.Struct
|
||||
primitiveOnStack :=
|
||||
(isInt && numInts >= numOfIntegerRegisters()) ||
|
||||
(isFloat && numFloats >= numOfFloatRegisters())
|
||||
if primitiveOnStack {
|
||||
return true
|
||||
}
|
||||
if kind != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
hfa := isHFA(v.Type())
|
||||
hva := isHVA(v.Type())
|
||||
size := v.Type().Size()
|
||||
eligible := hfa || hva || size <= 16
|
||||
if !eligible {
|
||||
return false
|
||||
}
|
||||
|
||||
if hfa {
|
||||
need := v.NumField()
|
||||
return numFloats+need > numOfFloatRegisters()
|
||||
}
|
||||
|
||||
if hva {
|
||||
need := v.NumField()
|
||||
return numInts+need > numOfIntegerRegisters()
|
||||
}
|
||||
|
||||
slotsNeeded := int((size + align8ByteMask) / align8ByteSize)
|
||||
return numInts+slotsNeeded > numOfIntegerRegisters()
|
||||
}
|
||||
|
||||
// structFitsInRegisters determines if a struct can still fit in remaining
|
||||
// registers, used during stack argument bundling to decide if a struct
|
||||
// should go through normal register allocation or be bundled with stack args.
|
||||
func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: structFitsInRegisters should only be called on darwin")
|
||||
}
|
||||
hfa := isHFA(val.Type())
|
||||
hva := isHVA(val.Type())
|
||||
size := val.Type().Size()
|
||||
|
||||
if hfa {
|
||||
// HFA: check if elements fit in float registers
|
||||
if tempNumFloats+val.NumField() <= numOfFloatRegisters() {
|
||||
return true, tempNumInts, tempNumFloats + val.NumField()
|
||||
}
|
||||
} else if hva {
|
||||
// HVA: check if elements fit in int registers
|
||||
if tempNumInts+val.NumField() <= numOfIntegerRegisters() {
|
||||
return true, tempNumInts + val.NumField(), tempNumFloats
|
||||
}
|
||||
} else if size <= 16 {
|
||||
// Non-HFA/HVA small structs use int registers for byte-packing
|
||||
slotsNeeded := int((size + align8ByteMask) / align8ByteSize)
|
||||
if tempNumInts+slotsNeeded <= numOfIntegerRegisters() {
|
||||
return true, tempNumInts + slotsNeeded, tempNumFloats
|
||||
}
|
||||
}
|
||||
|
||||
return false, tempNumInts, tempNumFloats
|
||||
}
|
||||
|
||||
// collectStackArgs separates remaining arguments into those that fit in registers vs those that go on stack.
|
||||
// It returns the stack arguments and processes register arguments through addValue.
|
||||
func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
|
||||
keepAlive []any, addInt, addFloat, addStack func(uintptr),
|
||||
pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: collectStackArgs should only be called on darwin")
|
||||
}
|
||||
|
||||
var stackArgs []reflect.Value
|
||||
tempNumInts := numInts
|
||||
tempNumFloats := numFloats
|
||||
|
||||
for j, val := range args[startIdx:] {
|
||||
// Determine if this argument goes to register or stack
|
||||
var fitsInRegister bool
|
||||
var newNumInts, newNumFloats int
|
||||
|
||||
if val.Kind() == reflect.Struct {
|
||||
// Check if struct still fits in remaining registers
|
||||
fitsInRegister, newNumInts, newNumFloats = structFitsInRegisters(val, tempNumInts, tempNumFloats)
|
||||
} else {
|
||||
// Primitive argument
|
||||
isFloat := val.Kind() == reflect.Float32 || val.Kind() == reflect.Float64
|
||||
if isFloat {
|
||||
fitsInRegister = tempNumFloats < numOfFloatRegisters()
|
||||
newNumFloats = tempNumFloats + 1
|
||||
newNumInts = tempNumInts
|
||||
} else {
|
||||
fitsInRegister = tempNumInts < numOfIntegerRegisters()
|
||||
newNumInts = tempNumInts + 1
|
||||
newNumFloats = tempNumFloats
|
||||
}
|
||||
}
|
||||
|
||||
if fitsInRegister {
|
||||
// Process through normal register allocation
|
||||
tempNumInts = newNumInts
|
||||
tempNumFloats = newNumFloats
|
||||
keepAlive = addValue(val, keepAlive, addInt, addFloat, addStack, pNumInts, pNumFloats, pNumStack)
|
||||
} else {
|
||||
// Convert strings to C strings before bundling
|
||||
if val.Kind() == reflect.String {
|
||||
ptr := strings.CString(val.String())
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
val = reflect.ValueOf(ptr)
|
||||
args[startIdx+j] = val
|
||||
}
|
||||
stackArgs = append(stackArgs, val)
|
||||
}
|
||||
}
|
||||
|
||||
return stackArgs, keepAlive
|
||||
}
|
||||
|
||||
const (
|
||||
paddingFieldPrefix = "Pad"
|
||||
)
|
||||
|
||||
// bundleStackArgs bundles remaining arguments for Darwin ARM64 C-style stack packing.
|
||||
// It creates a packed struct with proper alignment and copies it to the stack in 8-byte chunks.
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
if runtime.GOOS != "darwin" {
|
||||
panic("purego: bundleStackArgs should only be called on darwin")
|
||||
}
|
||||
if len(stackArgs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
// Build struct fields with proper C alignment and padding
|
||||
var fields []reflect.StructField
|
||||
currentOffset := uintptr(0)
|
||||
fieldIndex := 0
|
||||
|
||||
for j, val := range stackArgs {
|
||||
valSize := val.Type().Size()
|
||||
valAlign := val.Type().Align()
|
||||
|
||||
// ARM64 requires 8-byte alignment for 8-byte or larger structs
|
||||
if val.Kind() == reflect.Struct && valSize >= 8 {
|
||||
valAlign = 8
|
||||
}
|
||||
|
||||
// Add padding field if needed for alignment
|
||||
if currentOffset%uintptr(valAlign) != 0 {
|
||||
paddingNeeded := uintptr(valAlign) - (currentOffset % uintptr(valAlign))
|
||||
fields = append(fields, reflect.StructField{
|
||||
Name: paddingFieldPrefix + strconv.Itoa(fieldIndex),
|
||||
Type: reflect.ArrayOf(int(paddingNeeded), reflect.TypeOf(byte(0))),
|
||||
})
|
||||
currentOffset += paddingNeeded
|
||||
fieldIndex++
|
||||
}
|
||||
|
||||
fields = append(fields, reflect.StructField{
|
||||
Name: "X" + strconv.Itoa(j),
|
||||
Type: val.Type(),
|
||||
})
|
||||
currentOffset += valSize
|
||||
fieldIndex++
|
||||
}
|
||||
|
||||
// Create and populate the packed struct
|
||||
structType := reflect.StructOf(fields)
|
||||
structInstance := reflect.New(structType).Elem()
|
||||
|
||||
// Set values (skip padding fields)
|
||||
argIndex := 0
|
||||
for j := 0; j < structInstance.NumField(); j++ {
|
||||
fieldName := structType.Field(j).Name
|
||||
if stdstrings.HasPrefix(fieldName, paddingFieldPrefix) {
|
||||
continue
|
||||
}
|
||||
structInstance.Field(j).Set(stackArgs[argIndex])
|
||||
argIndex++
|
||||
}
|
||||
|
||||
ptr := unsafe.Pointer(structInstance.Addr().Pointer())
|
||||
size := structType.Size()
|
||||
copyStruct8ByteChunks(ptr, size, addStack)
|
||||
}
|
||||
|
||||
213
vendor/github.com/ebitengine/purego/struct_loong64.go
generated
vendored
Normal file
213
vendor/github.com/ebitengine/purego/struct_loong64.go
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
|
||||
outSize := outType.Size()
|
||||
switch {
|
||||
case outSize == 0:
|
||||
return reflect.New(outType).Elem()
|
||||
case outSize <= 8:
|
||||
r1 := syscall.a1
|
||||
if isAllFloats, numFields := isAllSameFloat(outType); isAllFloats {
|
||||
r1 = syscall.f1
|
||||
if numFields == 2 {
|
||||
r1 = syscall.f2<<32 | syscall.f1
|
||||
}
|
||||
}
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&struct{ a uintptr }{r1})).Elem()
|
||||
case outSize <= 16:
|
||||
r1, r2 := syscall.a1, syscall.a2
|
||||
if isAllFloats, numFields := isAllSameFloat(outType); isAllFloats {
|
||||
switch numFields {
|
||||
case 4:
|
||||
r1 = syscall.f2<<32 | syscall.f1
|
||||
r2 = syscall.f4<<32 | syscall.f3
|
||||
case 3:
|
||||
r1 = syscall.f2<<32 | syscall.f1
|
||||
r2 = syscall.f3
|
||||
case 2:
|
||||
r1 = syscall.f1
|
||||
r2 = syscall.f2
|
||||
default:
|
||||
panic("unreachable")
|
||||
}
|
||||
}
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&struct{ a, b uintptr }{r1, r2})).Elem()
|
||||
default:
|
||||
// create struct from the Go pointer created above
|
||||
// weird pointer dereference to circumvent go vet
|
||||
return reflect.NewAt(outType, *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))).Elem()
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
_NO_CLASS = 0b00
|
||||
_FLOAT = 0b01
|
||||
_INT = 0b11
|
||||
)
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []any) []any {
|
||||
if v.Type().Size() == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
if size := v.Type().Size(); size <= 16 {
|
||||
placeRegisters(v, addFloat, addInt)
|
||||
} else {
|
||||
keepAlive = placeStack(v, keepAlive, addInt)
|
||||
}
|
||||
return keepAlive // the struct was allocated so don't panic
|
||||
}
|
||||
|
||||
func placeRegisters(v reflect.Value, addFloat func(uintptr), addInt func(uintptr)) {
|
||||
var val uint64
|
||||
var shift byte
|
||||
var flushed bool
|
||||
class := _NO_CLASS
|
||||
var place func(v reflect.Value)
|
||||
place = func(v reflect.Value) {
|
||||
var numFields int
|
||||
if v.Kind() == reflect.Struct {
|
||||
numFields = v.Type().NumField()
|
||||
} else {
|
||||
numFields = v.Type().Len()
|
||||
}
|
||||
for k := 0; k < numFields; k++ {
|
||||
flushed = false
|
||||
var f reflect.Value
|
||||
if v.Kind() == reflect.Struct {
|
||||
f = v.Field(k)
|
||||
} else {
|
||||
f = v.Index(k)
|
||||
}
|
||||
align := byte(f.Type().Align()*8 - 1)
|
||||
shift = (shift + align) &^ align
|
||||
if shift >= 64 {
|
||||
shift = 0
|
||||
flushed = true
|
||||
if class == _FLOAT {
|
||||
addFloat(uintptr(val))
|
||||
} else {
|
||||
addInt(uintptr(val))
|
||||
}
|
||||
}
|
||||
switch f.Type().Kind() {
|
||||
case reflect.Struct:
|
||||
place(f)
|
||||
case reflect.Bool:
|
||||
if f.Bool() {
|
||||
val |= 1 << shift
|
||||
}
|
||||
shift += 8
|
||||
class |= _INT
|
||||
case reflect.Uint8:
|
||||
val |= f.Uint() << shift
|
||||
shift += 8
|
||||
class |= _INT
|
||||
case reflect.Uint16:
|
||||
val |= f.Uint() << shift
|
||||
shift += 16
|
||||
class |= _INT
|
||||
case reflect.Uint32:
|
||||
val |= f.Uint() << shift
|
||||
shift += 32
|
||||
class |= _INT
|
||||
case reflect.Uint64, reflect.Uint, reflect.Uintptr:
|
||||
addInt(uintptr(f.Uint()))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Int8:
|
||||
val |= uint64(f.Int()&0xFF) << shift
|
||||
shift += 8
|
||||
class |= _INT
|
||||
case reflect.Int16:
|
||||
val |= uint64(f.Int()&0xFFFF) << shift
|
||||
shift += 16
|
||||
class |= _INT
|
||||
case reflect.Int32:
|
||||
val |= uint64(f.Int()&0xFFFF_FFFF) << shift
|
||||
shift += 32
|
||||
class |= _INT
|
||||
case reflect.Int64, reflect.Int:
|
||||
addInt(uintptr(f.Int()))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Float32:
|
||||
if class == _FLOAT {
|
||||
addFloat(uintptr(val))
|
||||
val = 0
|
||||
shift = 0
|
||||
}
|
||||
val |= uint64(math.Float32bits(float32(f.Float()))) << shift
|
||||
shift += 32
|
||||
class |= _FLOAT
|
||||
case reflect.Float64:
|
||||
addFloat(uintptr(math.Float64bits(float64(f.Float()))))
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Ptr, reflect.UnsafePointer:
|
||||
addInt(f.Pointer())
|
||||
shift = 0
|
||||
flushed = true
|
||||
class = _NO_CLASS
|
||||
case reflect.Array:
|
||||
place(f)
|
||||
default:
|
||||
panic("purego: unsupported kind " + f.Kind().String())
|
||||
}
|
||||
}
|
||||
}
|
||||
place(v)
|
||||
if !flushed {
|
||||
if class == _FLOAT {
|
||||
addFloat(uintptr(val))
|
||||
} else {
|
||||
addInt(uintptr(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func placeStack(v reflect.Value, keepAlive []any, addInt func(uintptr)) []any {
|
||||
// Struct is too big to be placed in registers.
|
||||
// Copy to heap and place the pointer in register
|
||||
ptrStruct := reflect.New(v.Type())
|
||||
ptrStruct.Elem().Set(v)
|
||||
ptr := ptrStruct.Elem().Addr().UnsafePointer()
|
||||
keepAlive = append(keepAlive, ptr)
|
||||
addInt(uintptr(ptr))
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// shouldBundleStackArgs always returns false on loong64
|
||||
// since C-style stack argument bundling is only needed on Darwin ARM64.
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// structFitsInRegisters is not used on loong64.
|
||||
func structFitsInRegisters(val reflect.Value, tempNumInts, tempNumFloats int) (bool, int, int) {
|
||||
panic("purego: structFitsInRegisters should not be called on loong64")
|
||||
}
|
||||
|
||||
// collectStackArgs is not used on loong64.
|
||||
func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int,
|
||||
keepAlive []any, addInt, addFloat, addStack func(uintptr),
|
||||
pNumInts, pNumFloats, pNumStack *int) ([]reflect.Value, []any) {
|
||||
panic("purego: collectStackArgs should not be called on loong64")
|
||||
}
|
||||
|
||||
// bundleStackArgs is not used on loong64.
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("purego: bundleStackArgs should not be called on loong64")
|
||||
}
|
||||
16
vendor/github.com/ebitengine/purego/struct_other.go
generated
vendored
16
vendor/github.com/ebitengine/purego/struct_other.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2024 The Ebitengine Authors
|
||||
|
||||
//go:build !amd64 && !arm64
|
||||
|
||||
package purego
|
||||
|
||||
import "reflect"
|
||||
|
||||
func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFloat, addStack func(uintptr), keepAlive []interface{}) []interface{} {
|
||||
panic("purego: struct arguments are not supported")
|
||||
}
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) {
|
||||
panic("purego: struct returns are not supported")
|
||||
}
|
||||
143
vendor/github.com/ebitengine/purego/struct_ppc64le.go
generated
vendored
Normal file
143
vendor/github.com/ebitengine/purego/struct_ppc64le.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value {
|
||||
outSize := outType.Size()
|
||||
|
||||
switch {
|
||||
case outSize == 0:
|
||||
return reflect.New(outType).Elem()
|
||||
|
||||
case outSize <= 16:
|
||||
// Reconstruct from registers by copying raw bytes
|
||||
var buf [16]byte
|
||||
|
||||
// Integer registers
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.a1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.a2
|
||||
}
|
||||
|
||||
// Homogeneous float aggregates override integer regs
|
||||
if isAllFloats, numFields := isAllSameFloat(outType); isAllFloats {
|
||||
if outType.Field(0).Type.Kind() == reflect.Float32 {
|
||||
// float32 values in FP regs
|
||||
f := []uintptr{syscall.f1, syscall.f2, syscall.f3, syscall.f4}
|
||||
for i := 0; i < numFields; i++ {
|
||||
*(*uint32)(unsafe.Pointer(&buf[i*4])) = uint32(f[i])
|
||||
}
|
||||
} else {
|
||||
// float64: whole register value is valid
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.f1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.f2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&buf[0])).Elem()
|
||||
|
||||
default:
|
||||
// Returned indirectly via pointer in a1
|
||||
ptr := *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))
|
||||
return reflect.NewAt(outType, ptr).Elem()
|
||||
}
|
||||
}
|
||||
|
||||
func addStruct(
|
||||
v reflect.Value,
|
||||
numInts, numFloats, numStack *int,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
if size == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
if size <= 16 {
|
||||
return placeSmallAggregatePPC64LE(v, addFloat, addInt, keepAlive)
|
||||
}
|
||||
|
||||
return placeStack(v, keepAlive, addInt)
|
||||
}
|
||||
|
||||
func placeSmallAggregatePPC64LE(
|
||||
v reflect.Value,
|
||||
addFloat, addInt func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
|
||||
var ptr unsafe.Pointer
|
||||
if v.CanAddr() {
|
||||
ptr = v.Addr().UnsafePointer()
|
||||
} else {
|
||||
tmp := reflect.New(v.Type())
|
||||
tmp.Elem().Set(v)
|
||||
ptr = tmp.UnsafePointer()
|
||||
keepAlive = append(keepAlive, tmp.Interface())
|
||||
}
|
||||
|
||||
var buf [16]byte
|
||||
src := unsafe.Slice((*byte)(ptr), size)
|
||||
copy(buf[:], src)
|
||||
|
||||
w0 := *(*uintptr)(unsafe.Pointer(&buf[0]))
|
||||
w1 := uintptr(0)
|
||||
if size > 8 {
|
||||
w1 = *(*uintptr)(unsafe.Pointer(&buf[8]))
|
||||
}
|
||||
|
||||
if isFloats, _ := isAllSameFloat(v.Type()); isFloats {
|
||||
addFloat(w0)
|
||||
if size > 8 {
|
||||
addFloat(w1)
|
||||
}
|
||||
} else {
|
||||
addInt(w0)
|
||||
if size > 8 {
|
||||
addInt(w1)
|
||||
}
|
||||
}
|
||||
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// placeStack is a fallback for structs that are too large to fit in registers
|
||||
func placeStack(v reflect.Value, keepAlive []any, addInt func(uintptr)) []any {
|
||||
if v.CanAddr() {
|
||||
addInt(v.Addr().Pointer())
|
||||
return keepAlive
|
||||
}
|
||||
ptr := reflect.New(v.Type())
|
||||
ptr.Elem().Set(v)
|
||||
addInt(ptr.Pointer())
|
||||
return append(keepAlive, ptr.Interface())
|
||||
}
|
||||
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
// PPC64LE does not bundle stack args
|
||||
return false
|
||||
}
|
||||
|
||||
func collectStackArgs(
|
||||
args []reflect.Value,
|
||||
i, numInts, numFloats int,
|
||||
keepAlive []any,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
numIntsPtr, numFloatsPtr, numStackPtr *int,
|
||||
) ([]reflect.Value, []any) {
|
||||
return nil, keepAlive
|
||||
}
|
||||
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("bundleStackArgs not supported on PPC64LE")
|
||||
}
|
||||
143
vendor/github.com/ebitengine/purego/struct_riscv64.go
generated
vendored
Normal file
143
vendor/github.com/ebitengine/purego/struct_riscv64.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value {
|
||||
outSize := outType.Size()
|
||||
|
||||
switch {
|
||||
case outSize == 0:
|
||||
return reflect.New(outType).Elem()
|
||||
|
||||
case outSize <= 16:
|
||||
// Reconstruct from registers by copying raw bytes
|
||||
var buf [16]byte
|
||||
|
||||
// Integer registers
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.a1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.a2
|
||||
}
|
||||
|
||||
// Homogeneous float aggregates override integer regs
|
||||
if isAllFloats, numFields := isAllSameFloat(outType); isAllFloats {
|
||||
if outType.Field(0).Type.Kind() == reflect.Float32 {
|
||||
// float32 values are NaN-boxed in FP regs; use low 32 bits only
|
||||
f := []uintptr{syscall.f1, syscall.f2, syscall.f3, syscall.f4}
|
||||
for i := 0; i < numFields; i++ {
|
||||
*(*uint32)(unsafe.Pointer(&buf[i*4])) = uint32(f[i])
|
||||
}
|
||||
} else {
|
||||
// float64: whole register value is valid
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.f1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.f2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&buf[0])).Elem()
|
||||
|
||||
default:
|
||||
// Returned indirectly via pointer in a1
|
||||
ptr := *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))
|
||||
return reflect.NewAt(outType, ptr).Elem()
|
||||
}
|
||||
}
|
||||
|
||||
func addStruct(
|
||||
v reflect.Value,
|
||||
numInts, numFloats, numStack *int,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
if size == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
if size <= 16 {
|
||||
return placeSmallAggregateRISCV64(v, addFloat, addInt, keepAlive)
|
||||
}
|
||||
|
||||
return placeStack(v, keepAlive, addInt)
|
||||
}
|
||||
|
||||
func placeSmallAggregateRISCV64(
|
||||
v reflect.Value,
|
||||
addFloat, addInt func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
|
||||
var ptr unsafe.Pointer
|
||||
if v.CanAddr() {
|
||||
ptr = v.Addr().UnsafePointer()
|
||||
} else {
|
||||
tmp := reflect.New(v.Type())
|
||||
tmp.Elem().Set(v)
|
||||
ptr = tmp.UnsafePointer()
|
||||
keepAlive = append(keepAlive, tmp.Interface())
|
||||
}
|
||||
|
||||
var buf [16]byte
|
||||
src := unsafe.Slice((*byte)(ptr), size)
|
||||
copy(buf[:], src)
|
||||
|
||||
w0 := *(*uintptr)(unsafe.Pointer(&buf[0]))
|
||||
w1 := uintptr(0)
|
||||
if size > 8 {
|
||||
w1 = *(*uintptr)(unsafe.Pointer(&buf[8]))
|
||||
}
|
||||
|
||||
if isFloats, _ := isAllSameFloat(v.Type()); isFloats {
|
||||
addFloat(w0)
|
||||
if size > 8 {
|
||||
addFloat(w1)
|
||||
}
|
||||
} else {
|
||||
addInt(w0)
|
||||
if size > 8 {
|
||||
addInt(w1)
|
||||
}
|
||||
}
|
||||
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// placeStack is a fallback for structs that are too large to fit in registers
|
||||
func placeStack(v reflect.Value, keepAlive []any, addInt func(uintptr)) []any {
|
||||
if v.CanAddr() {
|
||||
addInt(v.Addr().Pointer())
|
||||
return keepAlive
|
||||
}
|
||||
ptr := reflect.New(v.Type())
|
||||
ptr.Elem().Set(v)
|
||||
addInt(ptr.Pointer())
|
||||
return append(keepAlive, ptr.Interface())
|
||||
}
|
||||
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
// RISCV64 does not bundle stack args
|
||||
return false
|
||||
}
|
||||
|
||||
func collectStackArgs(
|
||||
args []reflect.Value,
|
||||
i, numInts, numFloats int,
|
||||
keepAlive []any,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
numIntsPtr, numFloatsPtr, numStackPtr *int,
|
||||
) ([]reflect.Value, []any) {
|
||||
return nil, keepAlive
|
||||
}
|
||||
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("bundleStackArgs not supported on RISCV64")
|
||||
}
|
||||
143
vendor/github.com/ebitengine/purego/struct_s390x.go
generated
vendored
Normal file
143
vendor/github.com/ebitengine/purego/struct_s390x.go
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
package purego
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value {
|
||||
outSize := outType.Size()
|
||||
|
||||
switch {
|
||||
case outSize == 0:
|
||||
return reflect.New(outType).Elem()
|
||||
|
||||
case outSize <= 16:
|
||||
// Reconstruct from registers by copying raw bytes
|
||||
var buf [16]byte
|
||||
|
||||
// Integer registers
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.a1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.a2
|
||||
}
|
||||
|
||||
// Homogeneous float aggregates override integer regs
|
||||
if isAllFloats, numFields := isAllSameFloat(outType); isAllFloats {
|
||||
if outType.Field(0).Type.Kind() == reflect.Float32 {
|
||||
// float32 values in FP regs
|
||||
f := []uintptr{syscall.f1, syscall.f2, syscall.f3, syscall.f4}
|
||||
for i := 0; i < numFields; i++ {
|
||||
*(*uint32)(unsafe.Pointer(&buf[i*4])) = uint32(f[i])
|
||||
}
|
||||
} else {
|
||||
// float64: whole register value is valid
|
||||
*(*uintptr)(unsafe.Pointer(&buf[0])) = syscall.f1
|
||||
if outSize > 8 {
|
||||
*(*uintptr)(unsafe.Pointer(&buf[8])) = syscall.f2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return reflect.NewAt(outType, unsafe.Pointer(&buf[0])).Elem()
|
||||
|
||||
default:
|
||||
// Returned indirectly via pointer in a1
|
||||
ptr := *(*unsafe.Pointer)(unsafe.Pointer(&syscall.a1))
|
||||
return reflect.NewAt(outType, ptr).Elem()
|
||||
}
|
||||
}
|
||||
|
||||
func addStruct(
|
||||
v reflect.Value,
|
||||
numInts, numFloats, numStack *int,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
if size == 0 {
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
if size <= 16 {
|
||||
return placeSmallAggregateS390X(v, addFloat, addInt, keepAlive)
|
||||
}
|
||||
|
||||
return placeStack(v, keepAlive, addInt)
|
||||
}
|
||||
|
||||
func placeSmallAggregateS390X(
|
||||
v reflect.Value,
|
||||
addFloat, addInt func(uintptr),
|
||||
keepAlive []any,
|
||||
) []any {
|
||||
size := v.Type().Size()
|
||||
|
||||
var ptr unsafe.Pointer
|
||||
if v.CanAddr() {
|
||||
ptr = v.Addr().UnsafePointer()
|
||||
} else {
|
||||
tmp := reflect.New(v.Type())
|
||||
tmp.Elem().Set(v)
|
||||
ptr = tmp.UnsafePointer()
|
||||
keepAlive = append(keepAlive, tmp.Interface())
|
||||
}
|
||||
|
||||
var buf [16]byte
|
||||
src := unsafe.Slice((*byte)(ptr), size)
|
||||
copy(buf[:], src)
|
||||
|
||||
w0 := *(*uintptr)(unsafe.Pointer(&buf[0]))
|
||||
w1 := uintptr(0)
|
||||
if size > 8 {
|
||||
w1 = *(*uintptr)(unsafe.Pointer(&buf[8]))
|
||||
}
|
||||
|
||||
if isFloats, _ := isAllSameFloat(v.Type()); isFloats {
|
||||
addFloat(w0)
|
||||
if size > 8 {
|
||||
addFloat(w1)
|
||||
}
|
||||
} else {
|
||||
addInt(w0)
|
||||
if size > 8 {
|
||||
addInt(w1)
|
||||
}
|
||||
}
|
||||
|
||||
return keepAlive
|
||||
}
|
||||
|
||||
// placeStack is a fallback for structs that are too large to fit in registers
|
||||
func placeStack(v reflect.Value, keepAlive []any, addInt func(uintptr)) []any {
|
||||
if v.CanAddr() {
|
||||
addInt(v.Addr().Pointer())
|
||||
return keepAlive
|
||||
}
|
||||
ptr := reflect.New(v.Type())
|
||||
ptr.Elem().Set(v)
|
||||
addInt(ptr.Pointer())
|
||||
return append(keepAlive, ptr.Interface())
|
||||
}
|
||||
|
||||
func shouldBundleStackArgs(v reflect.Value, numInts, numFloats int) bool {
|
||||
// S390X does not bundle stack args
|
||||
return false
|
||||
}
|
||||
|
||||
func collectStackArgs(
|
||||
args []reflect.Value,
|
||||
i, numInts, numFloats int,
|
||||
keepAlive []any,
|
||||
addInt, addFloat, addStack func(uintptr),
|
||||
numIntsPtr, numFloatsPtr, numStackPtr *int,
|
||||
) ([]reflect.Value, []any) {
|
||||
return nil, keepAlive
|
||||
}
|
||||
|
||||
func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) {
|
||||
panic("bundleStackArgs not supported on S390X")
|
||||
}
|
||||
147
vendor/github.com/ebitengine/purego/sys_386.s
generated
vendored
Normal file
147
vendor/github.com/ebitengine/purego/sys_386.s
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
#define STACK_SIZE 160
|
||||
#define PTR_ADDRESS (STACK_SIZE - 4)
|
||||
|
||||
// syscall15X calls a function in libc on behalf of the syscall package.
|
||||
// syscall15X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// ...
|
||||
// a32 uintptr
|
||||
// f1 uintptr
|
||||
// ...
|
||||
// f16 uintptr
|
||||
// arm64_r8 uintptr
|
||||
// }
|
||||
// syscall15X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
//
|
||||
// On i386 System V ABI, all arguments are passed on the stack.
|
||||
// Return value is in EAX (and EDX for 64-bit values).
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4
|
||||
DATA ·syscall15XABI0(SB)/4, $syscall15X(SB)
|
||||
TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0
|
||||
// Called via C calling convention: argument pointer at 4(SP)
|
||||
// NOT via Go calling convention
|
||||
// On i386, the first argument is at 4(SP) after CALL pushes return address
|
||||
MOVL 4(SP), AX // get pointer to syscall15Args
|
||||
|
||||
// Save callee-saved registers
|
||||
PUSHL BP
|
||||
PUSHL BX
|
||||
PUSHL SI
|
||||
PUSHL DI
|
||||
|
||||
MOVL AX, BX // save args pointer in BX
|
||||
|
||||
// Allocate stack space for C function arguments
|
||||
// i386 SysV: all 32 args on stack = 32 * 4 = 128 bytes
|
||||
// Plus 16 bytes for alignment and local storage
|
||||
SUBL $STACK_SIZE, SP
|
||||
MOVL BX, PTR_ADDRESS(SP) // save args pointer
|
||||
|
||||
// Load function pointer
|
||||
MOVL syscall15Args_fn(BX), AX
|
||||
MOVL AX, (PTR_ADDRESS-4)(SP) // save fn pointer
|
||||
|
||||
// Push all integer arguments onto the stack (a1-a32)
|
||||
// i386 SysV ABI: arguments pushed right-to-left, but we're
|
||||
// setting up the stack from low to high addresses
|
||||
MOVL syscall15Args_a1(BX), AX
|
||||
MOVL AX, 0(SP)
|
||||
MOVL syscall15Args_a2(BX), AX
|
||||
MOVL AX, 4(SP)
|
||||
MOVL syscall15Args_a3(BX), AX
|
||||
MOVL AX, 8(SP)
|
||||
MOVL syscall15Args_a4(BX), AX
|
||||
MOVL AX, 12(SP)
|
||||
MOVL syscall15Args_a5(BX), AX
|
||||
MOVL AX, 16(SP)
|
||||
MOVL syscall15Args_a6(BX), AX
|
||||
MOVL AX, 20(SP)
|
||||
MOVL syscall15Args_a7(BX), AX
|
||||
MOVL AX, 24(SP)
|
||||
MOVL syscall15Args_a8(BX), AX
|
||||
MOVL AX, 28(SP)
|
||||
MOVL syscall15Args_a9(BX), AX
|
||||
MOVL AX, 32(SP)
|
||||
MOVL syscall15Args_a10(BX), AX
|
||||
MOVL AX, 36(SP)
|
||||
MOVL syscall15Args_a11(BX), AX
|
||||
MOVL AX, 40(SP)
|
||||
MOVL syscall15Args_a12(BX), AX
|
||||
MOVL AX, 44(SP)
|
||||
MOVL syscall15Args_a13(BX), AX
|
||||
MOVL AX, 48(SP)
|
||||
MOVL syscall15Args_a14(BX), AX
|
||||
MOVL AX, 52(SP)
|
||||
MOVL syscall15Args_a15(BX), AX
|
||||
MOVL AX, 56(SP)
|
||||
MOVL syscall15Args_a16(BX), AX
|
||||
MOVL AX, 60(SP)
|
||||
MOVL syscall15Args_a17(BX), AX
|
||||
MOVL AX, 64(SP)
|
||||
MOVL syscall15Args_a18(BX), AX
|
||||
MOVL AX, 68(SP)
|
||||
MOVL syscall15Args_a19(BX), AX
|
||||
MOVL AX, 72(SP)
|
||||
MOVL syscall15Args_a20(BX), AX
|
||||
MOVL AX, 76(SP)
|
||||
MOVL syscall15Args_a21(BX), AX
|
||||
MOVL AX, 80(SP)
|
||||
MOVL syscall15Args_a22(BX), AX
|
||||
MOVL AX, 84(SP)
|
||||
MOVL syscall15Args_a23(BX), AX
|
||||
MOVL AX, 88(SP)
|
||||
MOVL syscall15Args_a24(BX), AX
|
||||
MOVL AX, 92(SP)
|
||||
MOVL syscall15Args_a25(BX), AX
|
||||
MOVL AX, 96(SP)
|
||||
MOVL syscall15Args_a26(BX), AX
|
||||
MOVL AX, 100(SP)
|
||||
MOVL syscall15Args_a27(BX), AX
|
||||
MOVL AX, 104(SP)
|
||||
MOVL syscall15Args_a28(BX), AX
|
||||
MOVL AX, 108(SP)
|
||||
MOVL syscall15Args_a29(BX), AX
|
||||
MOVL AX, 112(SP)
|
||||
MOVL syscall15Args_a30(BX), AX
|
||||
MOVL AX, 116(SP)
|
||||
MOVL syscall15Args_a31(BX), AX
|
||||
MOVL AX, 120(SP)
|
||||
MOVL syscall15Args_a32(BX), AX
|
||||
MOVL AX, 124(SP)
|
||||
|
||||
// Call the C function
|
||||
MOVL (PTR_ADDRESS-4)(SP), AX
|
||||
CALL AX
|
||||
|
||||
// Get args pointer back and save results
|
||||
MOVL PTR_ADDRESS(SP), BX
|
||||
MOVL AX, syscall15Args_a1(BX) // return value r1
|
||||
MOVL DX, syscall15Args_a2(BX) // return value r2 (for 64-bit returns)
|
||||
|
||||
// Save x87 FPU return value (ST0) to f1 field
|
||||
// On i386 System V ABI, float/double returns are in ST(0)
|
||||
// We save as float64 (8 bytes) to preserve precision
|
||||
FMOVDP F0, syscall15Args_f1(BX)
|
||||
|
||||
// Clean up stack
|
||||
ADDL $STACK_SIZE, SP
|
||||
|
||||
// Restore callee-saved registers
|
||||
POPL DI
|
||||
POPL SI
|
||||
POPL BX
|
||||
POPL BP
|
||||
|
||||
RET
|
||||
8
vendor/github.com/ebitengine/purego/sys_amd64.s
generated
vendored
8
vendor/github.com/ebitengine/purego/sys_amd64.s
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
//go:build darwin || freebsd || linux || netbsd
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_amd64.h"
|
||||
@@ -91,6 +91,12 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0
|
||||
MOVQ X0, syscall15Args_f1(DI) // f1
|
||||
MOVQ X1, syscall15Args_f2(DI) // f2
|
||||
|
||||
#ifdef GOOS_darwin
|
||||
CALL purego_error(SB)
|
||||
MOVD (AX), AX
|
||||
MOVD AX, syscall15Args_a3(DI) // save errno
|
||||
#endif
|
||||
|
||||
XORL AX, AX // no error (it's ignored anyway)
|
||||
ADDQ $STACK_SIZE, SP
|
||||
MOVQ BP, SP
|
||||
|
||||
142
vendor/github.com/ebitengine/purego/sys_arm.s
generated
vendored
Normal file
142
vendor/github.com/ebitengine/purego/sys_arm.s
generated
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
#define STACK_SIZE 128
|
||||
#define PTR_ADDRESS (STACK_SIZE - 4)
|
||||
|
||||
// syscall15X calls a function in libc on behalf of the syscall package.
|
||||
// syscall15X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// ...
|
||||
// a32 uintptr
|
||||
// f1 uintptr
|
||||
// ...
|
||||
// f16 uintptr
|
||||
// arm64_r8 uintptr
|
||||
// }
|
||||
// syscall15X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4
|
||||
DATA ·syscall15XABI0(SB)/4, $syscall15X(SB)
|
||||
TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0
|
||||
// Called via C calling convention: R0 = pointer to syscall15Args
|
||||
// NOT via Go calling convention
|
||||
// Save link register and callee-saved registers first
|
||||
MOVW.W R14, -4(R13) // save LR (decrement and store)
|
||||
MOVM.DB.W [R4, R5, R6, R7, R8, R9, R11], (R13) // save callee-saved regs
|
||||
|
||||
MOVW R0, R8
|
||||
SUB $STACK_SIZE, R13
|
||||
MOVW R8, PTR_ADDRESS(R13)
|
||||
|
||||
// Load function pointer first (before anything can corrupt R8)
|
||||
MOVW syscall15Args_fn(R8), R5
|
||||
MOVW R5, (PTR_ADDRESS-4)(R13) // save fn at offset 56
|
||||
|
||||
// Load floating point arguments
|
||||
// Each float64 spans 2 uintptr slots (8 bytes) on ARM32, so we skip by 2
|
||||
MOVD syscall15Args_f1(R8), F0 // f1+f2 -> D0
|
||||
MOVD syscall15Args_f3(R8), F1 // f3+f4 -> D1
|
||||
MOVD syscall15Args_f5(R8), F2 // f5+f6 -> D2
|
||||
MOVD syscall15Args_f7(R8), F3 // f7+f8 -> D3
|
||||
MOVD syscall15Args_f9(R8), F4 // f9+f10 -> D4
|
||||
MOVD syscall15Args_f11(R8), F5 // f11+f12 -> D5
|
||||
MOVD syscall15Args_f13(R8), F6 // f13+f14 -> D6
|
||||
MOVD syscall15Args_f15(R8), F7 // f15+f16 -> D7
|
||||
|
||||
// Load integer arguments into registers (R0-R3 for ARM EABI)
|
||||
MOVW syscall15Args_a1(R8), R0 // a1
|
||||
MOVW syscall15Args_a2(R8), R1 // a2
|
||||
MOVW syscall15Args_a3(R8), R2 // a3
|
||||
MOVW syscall15Args_a4(R8), R3 // a4
|
||||
|
||||
// push a5-a32 onto stack
|
||||
MOVW syscall15Args_a5(R8), R4
|
||||
MOVW R4, 0(R13)
|
||||
MOVW syscall15Args_a6(R8), R4
|
||||
MOVW R4, 4(R13)
|
||||
MOVW syscall15Args_a7(R8), R4
|
||||
MOVW R4, 8(R13)
|
||||
MOVW syscall15Args_a8(R8), R4
|
||||
MOVW R4, 12(R13)
|
||||
MOVW syscall15Args_a9(R8), R4
|
||||
MOVW R4, 16(R13)
|
||||
MOVW syscall15Args_a10(R8), R4
|
||||
MOVW R4, 20(R13)
|
||||
MOVW syscall15Args_a11(R8), R4
|
||||
MOVW R4, 24(R13)
|
||||
MOVW syscall15Args_a12(R8), R4
|
||||
MOVW R4, 28(R13)
|
||||
MOVW syscall15Args_a13(R8), R4
|
||||
MOVW R4, 32(R13)
|
||||
MOVW syscall15Args_a14(R8), R4
|
||||
MOVW R4, 36(R13)
|
||||
MOVW syscall15Args_a15(R8), R4
|
||||
MOVW R4, 40(R13)
|
||||
MOVW syscall15Args_a16(R8), R4
|
||||
MOVW R4, 44(R13)
|
||||
MOVW syscall15Args_a17(R8), R4
|
||||
MOVW R4, 48(R13)
|
||||
MOVW syscall15Args_a18(R8), R4
|
||||
MOVW R4, 52(R13)
|
||||
MOVW syscall15Args_a19(R8), R4
|
||||
MOVW R4, 56(R13)
|
||||
MOVW syscall15Args_a20(R8), R4
|
||||
MOVW R4, 60(R13)
|
||||
MOVW syscall15Args_a21(R8), R4
|
||||
MOVW R4, 64(R13)
|
||||
MOVW syscall15Args_a22(R8), R4
|
||||
MOVW R4, 68(R13)
|
||||
MOVW syscall15Args_a23(R8), R4
|
||||
MOVW R4, 72(R13)
|
||||
MOVW syscall15Args_a24(R8), R4
|
||||
MOVW R4, 76(R13)
|
||||
MOVW syscall15Args_a25(R8), R4
|
||||
MOVW R4, 80(R13)
|
||||
MOVW syscall15Args_a26(R8), R4
|
||||
MOVW R4, 84(R13)
|
||||
MOVW syscall15Args_a27(R8), R4
|
||||
MOVW R4, 88(R13)
|
||||
MOVW syscall15Args_a28(R8), R4
|
||||
MOVW R4, 92(R13)
|
||||
MOVW syscall15Args_a29(R8), R4
|
||||
MOVW R4, 96(R13)
|
||||
MOVW syscall15Args_a30(R8), R4
|
||||
MOVW R4, 100(R13)
|
||||
MOVW syscall15Args_a31(R8), R4
|
||||
MOVW R4, 104(R13)
|
||||
MOVW syscall15Args_a32(R8), R4
|
||||
MOVW R4, 108(R13)
|
||||
|
||||
// Load saved function pointer and call
|
||||
MOVW (PTR_ADDRESS-4)(R13), R4
|
||||
|
||||
// Use BLX for Thumb interworking - Go assembler doesn't support BLX Rn
|
||||
// BLX R4 = 0xE12FFF34 (ARM encoding, always condition)
|
||||
WORD $0xE12FFF34 // blx r4
|
||||
|
||||
// pop structure pointer
|
||||
MOVW PTR_ADDRESS(R13), R8
|
||||
ADD $STACK_SIZE, R13
|
||||
|
||||
// save R0, R1
|
||||
MOVW R0, syscall15Args_a1(R8)
|
||||
MOVW R1, syscall15Args_a2(R8)
|
||||
|
||||
// save f0-f3 (each float64 spans 2 uintptr slots on ARM32)
|
||||
MOVD F0, syscall15Args_f1(R8)
|
||||
MOVD F1, syscall15Args_f3(R8)
|
||||
MOVD F2, syscall15Args_f5(R8)
|
||||
MOVD F3, syscall15Args_f7(R8)
|
||||
|
||||
// Restore callee-saved registers and return
|
||||
MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, R11]
|
||||
MOVW.P 4(R13), R15 // pop LR into PC (return)
|
||||
7
vendor/github.com/ebitengine/purego/sys_arm64.s
generated
vendored
7
vendor/github.com/ebitengine/purego/sys_arm64.s
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
//go:build darwin || freebsd || linux || netbsd || windows
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
@@ -89,4 +89,9 @@ TEXT syscall15X(SB), NOSPLIT, $0
|
||||
FMOVD F2, syscall15Args_f3(R2) // save f2
|
||||
FMOVD F3, syscall15Args_f4(R2) // save f3
|
||||
|
||||
#ifdef GOOS_darwin
|
||||
BL purego_error(SB)
|
||||
MOVD (R0), R0
|
||||
MOVD R0, syscall15Args_a3(R2) // save errno
|
||||
#endif
|
||||
RET
|
||||
|
||||
96
vendor/github.com/ebitengine/purego/sys_loong64.s
generated
vendored
Normal file
96
vendor/github.com/ebitengine/purego/sys_loong64.s
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
#define STACK_SIZE 64
|
||||
#define PTR_ADDRESS (STACK_SIZE - 8)
|
||||
|
||||
// syscall15X calls a function in libc on behalf of the syscall package.
|
||||
// syscall15X takes a pointer to a struct like:
|
||||
// struct {
|
||||
// fn uintptr
|
||||
// a1 uintptr
|
||||
// a2 uintptr
|
||||
// a3 uintptr
|
||||
// a4 uintptr
|
||||
// a5 uintptr
|
||||
// a6 uintptr
|
||||
// a7 uintptr
|
||||
// a8 uintptr
|
||||
// a9 uintptr
|
||||
// a10 uintptr
|
||||
// a11 uintptr
|
||||
// a12 uintptr
|
||||
// a13 uintptr
|
||||
// a14 uintptr
|
||||
// a15 uintptr
|
||||
// r1 uintptr
|
||||
// r2 uintptr
|
||||
// err uintptr
|
||||
// }
|
||||
// syscall15X must be called on the g0 stack with the
|
||||
// C calling convention (use libcCall).
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
|
||||
TEXT syscall15X(SB), NOSPLIT, $0
|
||||
// push structure pointer
|
||||
SUBV $STACK_SIZE, R3
|
||||
MOVV R4, PTR_ADDRESS(R3)
|
||||
MOVV R4, R13
|
||||
|
||||
MOVD syscall15Args_f1(R13), F0 // f1
|
||||
MOVD syscall15Args_f2(R13), F1 // f2
|
||||
MOVD syscall15Args_f3(R13), F2 // f3
|
||||
MOVD syscall15Args_f4(R13), F3 // f4
|
||||
MOVD syscall15Args_f5(R13), F4 // f5
|
||||
MOVD syscall15Args_f6(R13), F5 // f6
|
||||
MOVD syscall15Args_f7(R13), F6 // f7
|
||||
MOVD syscall15Args_f8(R13), F7 // f8
|
||||
|
||||
MOVV syscall15Args_a1(R13), R4 // a1
|
||||
MOVV syscall15Args_a2(R13), R5 // a2
|
||||
MOVV syscall15Args_a3(R13), R6 // a3
|
||||
MOVV syscall15Args_a4(R13), R7 // a4
|
||||
MOVV syscall15Args_a5(R13), R8 // a5
|
||||
MOVV syscall15Args_a6(R13), R9 // a6
|
||||
MOVV syscall15Args_a7(R13), R10 // a7
|
||||
MOVV syscall15Args_a8(R13), R11 // a8
|
||||
|
||||
// push a9-a15 onto stack
|
||||
MOVV syscall15Args_a9(R13), R12
|
||||
MOVV R12, 0(R3)
|
||||
MOVV syscall15Args_a10(R13), R12
|
||||
MOVV R12, 8(R3)
|
||||
MOVV syscall15Args_a11(R13), R12
|
||||
MOVV R12, 16(R3)
|
||||
MOVV syscall15Args_a12(R13), R12
|
||||
MOVV R12, 24(R3)
|
||||
MOVV syscall15Args_a13(R13), R12
|
||||
MOVV R12, 32(R3)
|
||||
MOVV syscall15Args_a14(R13), R12
|
||||
MOVV R12, 40(R3)
|
||||
MOVV syscall15Args_a15(R13), R12
|
||||
MOVV R12, 48(R3)
|
||||
|
||||
MOVV syscall15Args_fn(R13), R12
|
||||
JAL (R12)
|
||||
|
||||
// pop structure pointer
|
||||
MOVV PTR_ADDRESS(R3), R13
|
||||
ADDV $STACK_SIZE, R3
|
||||
|
||||
// save R4, R5
|
||||
MOVV R4, syscall15Args_a1(R13)
|
||||
MOVV R5, syscall15Args_a2(R13)
|
||||
|
||||
// save f0-f3
|
||||
MOVD F0, syscall15Args_f1(R13)
|
||||
MOVD F1, syscall15Args_f2(R13)
|
||||
MOVD F2, syscall15Args_f3(R13)
|
||||
MOVD F3, syscall15Args_f4(R13)
|
||||
RET
|
||||
120
vendor/github.com/ebitengine/purego/sys_ppc64le.s
generated
vendored
Normal file
120
vendor/github.com/ebitengine/purego/sys_ppc64le.s
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// PPC64LE ELFv2 ABI:
|
||||
// - Integer args: R3-R10 (8 registers)
|
||||
// - Float args: F1-F8 (8 registers)
|
||||
// - Return: R3 (integer), F1 (float)
|
||||
// - Stack pointer: R1
|
||||
// - Link register: LR (special)
|
||||
// - TOC pointer: R2 (must preserve)
|
||||
|
||||
// Stack layout for ELFv2 ABI (aligned to 16 bytes):
|
||||
// From callee's perspective when we call BL (CTR):
|
||||
// 0(R1) - back chain (our old R1)
|
||||
// 8(R1) - CR save word (optional)
|
||||
// 16(R1) - LR save (optional, we save it)
|
||||
// 24(R1) - Reserved (compilers)
|
||||
// 32(R1) - Parameter save area start (8 * 8 = 64 bytes for R3-R10)
|
||||
// 96(R1) - First stack arg (a9) - this is where callee looks
|
||||
// 104(R1) - Second stack arg (a10)
|
||||
// 112-152 - Stack args a11-a15 (5 * 8 = 40 bytes)
|
||||
// 160(R1) - TOC save (we put it here, outside param save area)
|
||||
// 168(R1) - saved args pointer
|
||||
// 176(R1) - padding for 16-byte alignment
|
||||
// Total: 176 bytes
|
||||
|
||||
#define STACK_SIZE 176
|
||||
#define LR_SAVE 16
|
||||
#define TOC_SAVE 160
|
||||
#define ARGP_SAVE 168
|
||||
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
|
||||
|
||||
TEXT syscall15X(SB), NOSPLIT, $0
|
||||
// Prologue: create stack frame
|
||||
// R3 contains the args pointer on entry
|
||||
MOVD R1, R12 // save old SP
|
||||
SUB $STACK_SIZE, R1 // allocate stack frame
|
||||
MOVD R12, 0(R1) // save back chain
|
||||
MOVD LR, R12
|
||||
MOVD R12, LR_SAVE(R1) // save LR
|
||||
MOVD R2, TOC_SAVE(R1) // save TOC
|
||||
|
||||
// Save args pointer (in R3)
|
||||
MOVD R3, ARGP_SAVE(R1)
|
||||
|
||||
// R11 := args pointer (syscall15Args*)
|
||||
MOVD R3, R11
|
||||
|
||||
// Load float args into F1-F8
|
||||
FMOVD syscall15Args_f1(R11), F1
|
||||
FMOVD syscall15Args_f2(R11), F2
|
||||
FMOVD syscall15Args_f3(R11), F3
|
||||
FMOVD syscall15Args_f4(R11), F4
|
||||
FMOVD syscall15Args_f5(R11), F5
|
||||
FMOVD syscall15Args_f6(R11), F6
|
||||
FMOVD syscall15Args_f7(R11), F7
|
||||
FMOVD syscall15Args_f8(R11), F8
|
||||
|
||||
// Load integer args into R3-R10
|
||||
MOVD syscall15Args_a1(R11), R3
|
||||
MOVD syscall15Args_a2(R11), R4
|
||||
MOVD syscall15Args_a3(R11), R5
|
||||
MOVD syscall15Args_a4(R11), R6
|
||||
MOVD syscall15Args_a5(R11), R7
|
||||
MOVD syscall15Args_a6(R11), R8
|
||||
MOVD syscall15Args_a7(R11), R9
|
||||
MOVD syscall15Args_a8(R11), R10
|
||||
|
||||
// Spill a9-a15 onto the stack (stack parameters start at 96(R1))
|
||||
// Per ELFv2: parameter save area is 32-95, stack args start at 96
|
||||
MOVD ARGP_SAVE(R1), R11 // reload args pointer
|
||||
MOVD syscall15Args_a9(R11), R12
|
||||
MOVD R12, 96(R1) // a9 at 96(R1)
|
||||
MOVD syscall15Args_a10(R11), R12
|
||||
MOVD R12, 104(R1) // a10 at 104(R1)
|
||||
MOVD syscall15Args_a11(R11), R12
|
||||
MOVD R12, 112(R1) // a11 at 112(R1)
|
||||
MOVD syscall15Args_a12(R11), R12
|
||||
MOVD R12, 120(R1) // a12 at 120(R1)
|
||||
MOVD syscall15Args_a13(R11), R12
|
||||
MOVD R12, 128(R1) // a13 at 128(R1)
|
||||
MOVD syscall15Args_a14(R11), R12
|
||||
MOVD R12, 136(R1) // a14 at 136(R1)
|
||||
MOVD syscall15Args_a15(R11), R12
|
||||
MOVD R12, 144(R1) // a15 at 144(R1)
|
||||
|
||||
// Call function: load fn and call
|
||||
MOVD syscall15Args_fn(R11), R12
|
||||
MOVD R12, CTR
|
||||
BL (CTR)
|
||||
|
||||
// Restore TOC after call
|
||||
MOVD TOC_SAVE(R1), R2
|
||||
|
||||
// Restore args pointer for storing results
|
||||
MOVD ARGP_SAVE(R1), R11
|
||||
|
||||
// Store integer results back (R3, R4)
|
||||
MOVD R3, syscall15Args_a1(R11)
|
||||
MOVD R4, syscall15Args_a2(R11)
|
||||
|
||||
// Store float return values (F1-F4)
|
||||
FMOVD F1, syscall15Args_f1(R11)
|
||||
FMOVD F2, syscall15Args_f2(R11)
|
||||
FMOVD F3, syscall15Args_f3(R11)
|
||||
FMOVD F4, syscall15Args_f4(R11)
|
||||
|
||||
// Epilogue: restore and return
|
||||
MOVD LR_SAVE(R1), R12
|
||||
MOVD R12, LR
|
||||
ADD $STACK_SIZE, R1
|
||||
RET
|
||||
101
vendor/github.com/ebitengine/purego/sys_riscv64.s
generated
vendored
Normal file
101
vendor/github.com/ebitengine/purego/sys_riscv64.s
generated
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// Stack usage:
|
||||
// 0(SP) - 56(SP): stack args a9-a15 (7 * 8 bytes = 56)
|
||||
// 56(SP) - 64(SP): saved RA (x1)
|
||||
// 64(SP) - 72(SP): saved X9 (s1)
|
||||
// 72(SP) - 80(SP): saved X18 (s2)
|
||||
// 80(SP) - 88(SP): saved args pointer (original X10)
|
||||
// 88(SP) - 96(SP): padding
|
||||
#define STACK_SIZE 96
|
||||
#define SAVE_RA 56
|
||||
#define SAVE_X9 64
|
||||
#define SAVE_X18 72
|
||||
#define SAVE_ARGP 80
|
||||
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
|
||||
|
||||
TEXT syscall15X(SB), NOSPLIT, $0
|
||||
// Allocate stack frame (keeps 16-byte alignment)
|
||||
SUB $STACK_SIZE, SP
|
||||
|
||||
// Save callee-saved regs we clobber + return address
|
||||
MOV X1, SAVE_RA(SP)
|
||||
MOV X9, SAVE_X9(SP)
|
||||
MOV X18, SAVE_X18(SP)
|
||||
|
||||
// Save original args pointer (in a0/X10)
|
||||
MOV X10, SAVE_ARGP(SP)
|
||||
|
||||
// X9 := args pointer (syscall15Args*)
|
||||
MOV X10, X9
|
||||
|
||||
// Load float args into fa0-fa7 (F10-F17)
|
||||
MOVD syscall15Args_f1(X9), F10
|
||||
MOVD syscall15Args_f2(X9), F11
|
||||
MOVD syscall15Args_f3(X9), F12
|
||||
MOVD syscall15Args_f4(X9), F13
|
||||
MOVD syscall15Args_f5(X9), F14
|
||||
MOVD syscall15Args_f6(X9), F15
|
||||
MOVD syscall15Args_f7(X9), F16
|
||||
MOVD syscall15Args_f8(X9), F17
|
||||
|
||||
// Load integer args into a0-a7 (X10-X17)
|
||||
MOV syscall15Args_a1(X9), X10
|
||||
MOV syscall15Args_a2(X9), X11
|
||||
MOV syscall15Args_a3(X9), X12
|
||||
MOV syscall15Args_a4(X9), X13
|
||||
MOV syscall15Args_a5(X9), X14
|
||||
MOV syscall15Args_a6(X9), X15
|
||||
MOV syscall15Args_a7(X9), X16
|
||||
MOV syscall15Args_a8(X9), X17
|
||||
|
||||
// Spill a9-a15 onto the stack (C ABI)
|
||||
MOV syscall15Args_a9(X9), X18
|
||||
MOV X18, 0(SP)
|
||||
MOV syscall15Args_a10(X9), X18
|
||||
MOV X18, 8(SP)
|
||||
MOV syscall15Args_a11(X9), X18
|
||||
MOV X18, 16(SP)
|
||||
MOV syscall15Args_a12(X9), X18
|
||||
MOV X18, 24(SP)
|
||||
MOV syscall15Args_a13(X9), X18
|
||||
MOV X18, 32(SP)
|
||||
MOV syscall15Args_a14(X9), X18
|
||||
MOV X18, 40(SP)
|
||||
MOV syscall15Args_a15(X9), X18
|
||||
MOV X18, 48(SP)
|
||||
|
||||
// Call fn
|
||||
// IMPORTANT: preserve RA across this call (we saved it above)
|
||||
MOV syscall15Args_fn(X9), X18
|
||||
CALL X18
|
||||
|
||||
// Restore args pointer (syscall15Args*) for storing results
|
||||
MOV SAVE_ARGP(SP), X9
|
||||
|
||||
// Store results back
|
||||
MOV X10, syscall15Args_a1(X9)
|
||||
MOV X11, syscall15Args_a2(X9)
|
||||
|
||||
// Store back float return regs if used by your ABI contract
|
||||
MOVD F10, syscall15Args_f1(X9)
|
||||
MOVD F11, syscall15Args_f2(X9)
|
||||
MOVD F12, syscall15Args_f3(X9)
|
||||
MOVD F13, syscall15Args_f4(X9)
|
||||
|
||||
// Restore callee-saved regs and return address
|
||||
MOV SAVE_X18(SP), X18
|
||||
MOV SAVE_X9(SP), X9
|
||||
MOV SAVE_RA(SP), X1
|
||||
|
||||
ADD $STACK_SIZE, SP
|
||||
RET
|
||||
114
vendor/github.com/ebitengine/purego/sys_s390x.s
generated
vendored
Normal file
114
vendor/github.com/ebitengine/purego/sys_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// S390X ELF ABI:
|
||||
// - Integer args: R2-R6 (5 registers)
|
||||
// - Float args: F0, F2, F4, F6 (4 registers, even-numbered)
|
||||
// - Return: R2 (integer), F0 (float)
|
||||
// - Stack pointer: R15
|
||||
// - Link register: R14
|
||||
// - Callee-saved: R6-R13, F8-F15 (but R6 is also used for 5th param)
|
||||
//
|
||||
// Stack frame layout (aligned to 8 bytes):
|
||||
// 0(R15) - back chain
|
||||
// 8(R15) - reserved
|
||||
// 16(R15) - reserved
|
||||
// ... - register save area (R6-R15 at 48(R15))
|
||||
// 160(R15) - parameter area start (args beyond registers)
|
||||
//
|
||||
// We need space for:
|
||||
// - 160 bytes standard frame (with register save area)
|
||||
// - Stack args a6-a15 (10 * 8 = 80 bytes)
|
||||
// - Saved args pointer (8 bytes)
|
||||
// - Padding for alignment
|
||||
// Total: 264 bytes (rounded to 8-byte alignment)
|
||||
|
||||
#define STACK_SIZE 264
|
||||
#define STACK_ARGS 160
|
||||
#define ARGP_SAVE 248
|
||||
|
||||
GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
|
||||
DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
|
||||
|
||||
TEXT syscall15X(SB), NOSPLIT, $0
|
||||
// On entry, R2 contains the args pointer
|
||||
// Save callee-saved registers in caller's frame (per ABI)
|
||||
STMG R6, R15, 48(R15)
|
||||
|
||||
// Allocate our stack frame
|
||||
MOVD R15, R1
|
||||
SUB $STACK_SIZE, R15
|
||||
MOVD R1, 0(R15) // back chain
|
||||
|
||||
// Save args pointer
|
||||
MOVD R2, ARGP_SAVE(R15)
|
||||
|
||||
// R9 := args pointer (syscall15Args*)
|
||||
MOVD R2, R9
|
||||
|
||||
// Load float args into F0, F2, F4, F6 (s390x uses even-numbered FPRs)
|
||||
FMOVD syscall15Args_f1(R9), F0
|
||||
FMOVD syscall15Args_f2(R9), F2
|
||||
FMOVD syscall15Args_f3(R9), F4
|
||||
FMOVD syscall15Args_f4(R9), F6
|
||||
|
||||
// Load integer args into R2-R6 (5 registers)
|
||||
MOVD syscall15Args_a1(R9), R2
|
||||
MOVD syscall15Args_a2(R9), R3
|
||||
MOVD syscall15Args_a3(R9), R4
|
||||
MOVD syscall15Args_a4(R9), R5
|
||||
MOVD syscall15Args_a5(R9), R6
|
||||
|
||||
// Spill remaining args (a6-a15) onto the stack at 160(R15)
|
||||
MOVD ARGP_SAVE(R15), R9 // reload args pointer
|
||||
MOVD syscall15Args_a6(R9), R1
|
||||
MOVD R1, (STACK_ARGS+0*8)(R15)
|
||||
MOVD syscall15Args_a7(R9), R1
|
||||
MOVD R1, (STACK_ARGS+1*8)(R15)
|
||||
MOVD syscall15Args_a8(R9), R1
|
||||
MOVD R1, (STACK_ARGS+2*8)(R15)
|
||||
MOVD syscall15Args_a9(R9), R1
|
||||
MOVD R1, (STACK_ARGS+3*8)(R15)
|
||||
MOVD syscall15Args_a10(R9), R1
|
||||
MOVD R1, (STACK_ARGS+4*8)(R15)
|
||||
MOVD syscall15Args_a11(R9), R1
|
||||
MOVD R1, (STACK_ARGS+5*8)(R15)
|
||||
MOVD syscall15Args_a12(R9), R1
|
||||
MOVD R1, (STACK_ARGS+6*8)(R15)
|
||||
MOVD syscall15Args_a13(R9), R1
|
||||
MOVD R1, (STACK_ARGS+7*8)(R15)
|
||||
MOVD syscall15Args_a14(R9), R1
|
||||
MOVD R1, (STACK_ARGS+8*8)(R15)
|
||||
MOVD syscall15Args_a15(R9), R1
|
||||
MOVD R1, (STACK_ARGS+9*8)(R15)
|
||||
|
||||
// Call function
|
||||
MOVD syscall15Args_fn(R9), R1
|
||||
BL (R1)
|
||||
|
||||
// Restore args pointer for storing results
|
||||
MOVD ARGP_SAVE(R15), R9
|
||||
|
||||
// Store integer results back (R2, R3)
|
||||
MOVD R2, syscall15Args_a1(R9)
|
||||
MOVD R3, syscall15Args_a2(R9)
|
||||
|
||||
// Store float return values (F0, F2, F4, F6)
|
||||
FMOVD F0, syscall15Args_f1(R9)
|
||||
FMOVD F2, syscall15Args_f2(R9)
|
||||
FMOVD F4, syscall15Args_f3(R9)
|
||||
FMOVD F6, syscall15Args_f4(R9)
|
||||
|
||||
// Deallocate stack frame
|
||||
ADD $STACK_SIZE, R15
|
||||
|
||||
// Restore callee-saved registers from caller's save area
|
||||
LMG 48(R15), R6, R15
|
||||
|
||||
RET
|
||||
226
vendor/github.com/ebitengine/purego/sys_unix_386.s
generated
vendored
Normal file
226
vendor/github.com/ebitengine/purego/sys_unix_386.s
generated
vendored
Normal file
@@ -0,0 +1,226 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// callbackasm1 is the second part of the callback trampoline.
|
||||
// On entry:
|
||||
// - CX contains the callback index (set by callbackasm)
|
||||
// - 0(SP) contains the return address to C caller
|
||||
// - 4(SP), 8(SP), ... contain C arguments (cdecl convention)
|
||||
//
|
||||
// i386 cdecl calling convention:
|
||||
// - All arguments passed on stack
|
||||
// - Return value in EAX (and EDX for 64-bit)
|
||||
// - Caller cleans the stack
|
||||
// - Callee must preserve: EBX, ESI, EDI, EBP
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// Save the return address
|
||||
MOVL 0(SP), AX
|
||||
|
||||
// Allocate stack frame (must be done carefully to preserve args access)
|
||||
// Layout:
|
||||
// 0-15: saved callee-saved registers (BX, SI, DI, BP)
|
||||
// 16-19: saved callback index
|
||||
// 20-23: saved return address
|
||||
// 24-35: callbackArgs struct (12 bytes)
|
||||
// 36-291: copy of C arguments (256 bytes for 64 args, matching callbackMaxFrame)
|
||||
// Total: 292 bytes, round up to 304 for alignment
|
||||
SUBL $304, SP
|
||||
|
||||
// Save callee-saved registers
|
||||
MOVL BX, 0(SP)
|
||||
MOVL SI, 4(SP)
|
||||
MOVL DI, 8(SP)
|
||||
MOVL BP, 12(SP)
|
||||
|
||||
// Save callback index and return address
|
||||
MOVL CX, 16(SP)
|
||||
MOVL AX, 20(SP)
|
||||
|
||||
// Copy C arguments from original stack location to our frame
|
||||
// Original args start at 304+4(SP) = 308(SP) (past our frame + original return addr)
|
||||
// Copy to our frame at 36(SP)
|
||||
// Copy 64 arguments (256 bytes, matching callbackMaxFrame = 64 * ptrSize)
|
||||
MOVL 308(SP), AX
|
||||
MOVL AX, 36(SP)
|
||||
MOVL 312(SP), AX
|
||||
MOVL AX, 40(SP)
|
||||
MOVL 316(SP), AX
|
||||
MOVL AX, 44(SP)
|
||||
MOVL 320(SP), AX
|
||||
MOVL AX, 48(SP)
|
||||
MOVL 324(SP), AX
|
||||
MOVL AX, 52(SP)
|
||||
MOVL 328(SP), AX
|
||||
MOVL AX, 56(SP)
|
||||
MOVL 332(SP), AX
|
||||
MOVL AX, 60(SP)
|
||||
MOVL 336(SP), AX
|
||||
MOVL AX, 64(SP)
|
||||
MOVL 340(SP), AX
|
||||
MOVL AX, 68(SP)
|
||||
MOVL 344(SP), AX
|
||||
MOVL AX, 72(SP)
|
||||
MOVL 348(SP), AX
|
||||
MOVL AX, 76(SP)
|
||||
MOVL 352(SP), AX
|
||||
MOVL AX, 80(SP)
|
||||
MOVL 356(SP), AX
|
||||
MOVL AX, 84(SP)
|
||||
MOVL 360(SP), AX
|
||||
MOVL AX, 88(SP)
|
||||
MOVL 364(SP), AX
|
||||
MOVL AX, 92(SP)
|
||||
MOVL 368(SP), AX
|
||||
MOVL AX, 96(SP)
|
||||
MOVL 372(SP), AX
|
||||
MOVL AX, 100(SP)
|
||||
MOVL 376(SP), AX
|
||||
MOVL AX, 104(SP)
|
||||
MOVL 380(SP), AX
|
||||
MOVL AX, 108(SP)
|
||||
MOVL 384(SP), AX
|
||||
MOVL AX, 112(SP)
|
||||
MOVL 388(SP), AX
|
||||
MOVL AX, 116(SP)
|
||||
MOVL 392(SP), AX
|
||||
MOVL AX, 120(SP)
|
||||
MOVL 396(SP), AX
|
||||
MOVL AX, 124(SP)
|
||||
MOVL 400(SP), AX
|
||||
MOVL AX, 128(SP)
|
||||
MOVL 404(SP), AX
|
||||
MOVL AX, 132(SP)
|
||||
MOVL 408(SP), AX
|
||||
MOVL AX, 136(SP)
|
||||
MOVL 412(SP), AX
|
||||
MOVL AX, 140(SP)
|
||||
MOVL 416(SP), AX
|
||||
MOVL AX, 144(SP)
|
||||
MOVL 420(SP), AX
|
||||
MOVL AX, 148(SP)
|
||||
MOVL 424(SP), AX
|
||||
MOVL AX, 152(SP)
|
||||
MOVL 428(SP), AX
|
||||
MOVL AX, 156(SP)
|
||||
MOVL 432(SP), AX
|
||||
MOVL AX, 160(SP)
|
||||
MOVL 436(SP), AX
|
||||
MOVL AX, 164(SP)
|
||||
MOVL 440(SP), AX
|
||||
MOVL AX, 168(SP)
|
||||
MOVL 444(SP), AX
|
||||
MOVL AX, 172(SP)
|
||||
MOVL 448(SP), AX
|
||||
MOVL AX, 176(SP)
|
||||
MOVL 452(SP), AX
|
||||
MOVL AX, 180(SP)
|
||||
MOVL 456(SP), AX
|
||||
MOVL AX, 184(SP)
|
||||
MOVL 460(SP), AX
|
||||
MOVL AX, 188(SP)
|
||||
MOVL 464(SP), AX
|
||||
MOVL AX, 192(SP)
|
||||
MOVL 468(SP), AX
|
||||
MOVL AX, 196(SP)
|
||||
MOVL 472(SP), AX
|
||||
MOVL AX, 200(SP)
|
||||
MOVL 476(SP), AX
|
||||
MOVL AX, 204(SP)
|
||||
MOVL 480(SP), AX
|
||||
MOVL AX, 208(SP)
|
||||
MOVL 484(SP), AX
|
||||
MOVL AX, 212(SP)
|
||||
MOVL 488(SP), AX
|
||||
MOVL AX, 216(SP)
|
||||
MOVL 492(SP), AX
|
||||
MOVL AX, 220(SP)
|
||||
MOVL 496(SP), AX
|
||||
MOVL AX, 224(SP)
|
||||
MOVL 500(SP), AX
|
||||
MOVL AX, 228(SP)
|
||||
MOVL 504(SP), AX
|
||||
MOVL AX, 232(SP)
|
||||
MOVL 508(SP), AX
|
||||
MOVL AX, 236(SP)
|
||||
MOVL 512(SP), AX
|
||||
MOVL AX, 240(SP)
|
||||
MOVL 516(SP), AX
|
||||
MOVL AX, 244(SP)
|
||||
MOVL 520(SP), AX
|
||||
MOVL AX, 248(SP)
|
||||
MOVL 524(SP), AX
|
||||
MOVL AX, 252(SP)
|
||||
MOVL 528(SP), AX
|
||||
MOVL AX, 256(SP)
|
||||
MOVL 532(SP), AX
|
||||
MOVL AX, 260(SP)
|
||||
MOVL 536(SP), AX
|
||||
MOVL AX, 264(SP)
|
||||
MOVL 540(SP), AX
|
||||
MOVL AX, 268(SP)
|
||||
MOVL 544(SP), AX
|
||||
MOVL AX, 272(SP)
|
||||
MOVL 548(SP), AX
|
||||
MOVL AX, 276(SP)
|
||||
MOVL 552(SP), AX
|
||||
MOVL AX, 280(SP)
|
||||
MOVL 556(SP), AX
|
||||
MOVL AX, 284(SP)
|
||||
MOVL 560(SP), AX
|
||||
MOVL AX, 288(SP)
|
||||
|
||||
// Set up callbackArgs struct at 24(SP)
|
||||
// struct callbackArgs {
|
||||
// index uintptr // offset 0
|
||||
// args *byte // offset 4
|
||||
// result uintptr // offset 8
|
||||
// }
|
||||
MOVL 16(SP), AX // callback index
|
||||
MOVL AX, 24(SP) // callbackArgs.index
|
||||
LEAL 36(SP), AX // pointer to copied arguments
|
||||
MOVL AX, 28(SP) // callbackArgs.args
|
||||
MOVL $0, 32(SP) // callbackArgs.result = 0
|
||||
|
||||
// Call crosscall2(fn, frame, 0, ctxt)
|
||||
// crosscall2 expects arguments on stack:
|
||||
// 0(SP) = fn
|
||||
// 4(SP) = frame (pointer to callbackArgs)
|
||||
// 8(SP) = ignored (was n)
|
||||
// 12(SP) = ctxt
|
||||
SUBL $16, SP
|
||||
|
||||
MOVL ·callbackWrap_call(SB), AX
|
||||
MOVL (AX), AX // fn = *callbackWrap_call
|
||||
MOVL AX, 0(SP) // fn
|
||||
LEAL (24+16)(SP), AX // &callbackArgs (adjusted for SUB $16)
|
||||
MOVL AX, 4(SP) // frame
|
||||
MOVL $0, 8(SP) // 0
|
||||
MOVL $0, 12(SP) // ctxt
|
||||
|
||||
CALL crosscall2(SB)
|
||||
|
||||
ADDL $16, SP
|
||||
|
||||
// Get result from callbackArgs.result
|
||||
MOVL 32(SP), AX
|
||||
|
||||
// Restore callee-saved registers
|
||||
MOVL 0(SP), BX
|
||||
MOVL 4(SP), SI
|
||||
MOVL 8(SP), DI
|
||||
MOVL 12(SP), BP
|
||||
|
||||
// Restore return address and clean up
|
||||
MOVL 20(SP), CX // get return address
|
||||
ADDL $304, SP // remove our frame
|
||||
MOVL CX, 0(SP) // put return address back
|
||||
|
||||
RET
|
||||
89
vendor/github.com/ebitengine/purego/sys_unix_arm.s
generated
vendored
Normal file
89
vendor/github.com/ebitengine/purego/sys_unix_arm.s
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// Allocate stack frame: 48 + 16 + 64 + 16 = 144 bytes
|
||||
SUB $144, R13
|
||||
|
||||
// Save callee-saved registers at SP+0
|
||||
MOVW R4, 0(R13)
|
||||
MOVW R5, 4(R13)
|
||||
MOVW R6, 8(R13)
|
||||
MOVW R7, 12(R13)
|
||||
MOVW R8, 16(R13)
|
||||
MOVW R9, 20(R13)
|
||||
MOVW g, 24(R13)
|
||||
MOVW R11, 28(R13)
|
||||
MOVW R14, 32(R13)
|
||||
|
||||
// Save callback index (passed in R12) at SP+36
|
||||
MOVW R12, 36(R13)
|
||||
|
||||
// Save integer arguments R0-R3 at SP+128 (frame[16..19])
|
||||
MOVW R0, 128(R13)
|
||||
MOVW R1, 132(R13)
|
||||
MOVW R2, 136(R13)
|
||||
MOVW R3, 140(R13)
|
||||
|
||||
// Save floating point registers F0-F7 at SP+64 (frame[0..15])
|
||||
// Note: We always save these since we target hard-float ABI.
|
||||
MOVD F0, 64(R13)
|
||||
MOVD F1, 72(R13)
|
||||
MOVD F2, 80(R13)
|
||||
MOVD F3, 88(R13)
|
||||
MOVD F4, 96(R13)
|
||||
MOVD F5, 104(R13)
|
||||
MOVD F6, 112(R13)
|
||||
MOVD F7, 120(R13)
|
||||
|
||||
// Set up callbackArgs at SP+48
|
||||
MOVW 36(R13), R4
|
||||
MOVW R4, 48(R13)
|
||||
ADD $64, R13, R4
|
||||
MOVW R4, 52(R13)
|
||||
MOVW $0, R4
|
||||
MOVW R4, 56(R13)
|
||||
|
||||
// Call crosscall2(fn, frame, 0, ctxt)
|
||||
MOVW ·callbackWrap_call(SB), R0
|
||||
MOVW (R0), R0
|
||||
ADD $48, R13, R1
|
||||
MOVW $0, R2
|
||||
MOVW $0, R3
|
||||
|
||||
BL crosscall2(SB)
|
||||
|
||||
// Get result
|
||||
MOVW 56(R13), R0
|
||||
|
||||
// Restore float registers
|
||||
MOVD 64(R13), F0
|
||||
MOVD 72(R13), F1
|
||||
MOVD 80(R13), F2
|
||||
MOVD 88(R13), F3
|
||||
MOVD 96(R13), F4
|
||||
MOVD 104(R13), F5
|
||||
MOVD 112(R13), F6
|
||||
MOVD 120(R13), F7
|
||||
|
||||
// Restore callee-saved registers
|
||||
MOVW 0(R13), R4
|
||||
MOVW 4(R13), R5
|
||||
MOVW 8(R13), R6
|
||||
MOVW 12(R13), R7
|
||||
MOVW 16(R13), R8
|
||||
MOVW 20(R13), R9
|
||||
MOVW 24(R13), g
|
||||
MOVW 28(R13), R11
|
||||
MOVW 32(R13), R14
|
||||
|
||||
ADD $144, R13
|
||||
RET
|
||||
2
vendor/github.com/ebitengine/purego/sys_unix_arm64.s
generated
vendored
2
vendor/github.com/ebitengine/purego/sys_unix_arm64.s
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2023 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
//go:build darwin || freebsd || linux || netbsd
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
75
vendor/github.com/ebitengine/purego/sys_unix_loong64.s
generated
vendored
Normal file
75
vendor/github.com/ebitengine/purego/sys_unix_loong64.s
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
#include "abi_loong64.h"
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
SUBV $(16*8), R3, R14
|
||||
MOVD F0, 0(R14)
|
||||
MOVD F1, 8(R14)
|
||||
MOVD F2, 16(R14)
|
||||
MOVD F3, 24(R14)
|
||||
MOVD F4, 32(R14)
|
||||
MOVD F5, 40(R14)
|
||||
MOVD F6, 48(R14)
|
||||
MOVD F7, 56(R14)
|
||||
MOVV R4, 64(R14)
|
||||
MOVV R5, 72(R14)
|
||||
MOVV R6, 80(R14)
|
||||
MOVV R7, 88(R14)
|
||||
MOVV R8, 96(R14)
|
||||
MOVV R9, 104(R14)
|
||||
MOVV R10, 112(R14)
|
||||
MOVV R11, 120(R14)
|
||||
|
||||
// Adjust SP by frame size.
|
||||
SUBV $(22*8), R3
|
||||
|
||||
// It is important to save R30 because the go assembler
|
||||
// uses it for move instructions for a variable.
|
||||
// This line:
|
||||
// MOVV ·callbackWrap_call(SB), R4
|
||||
// Creates the instructions:
|
||||
// PCALAU12I off1(PC), R30
|
||||
// MOVV off2(R30), R4
|
||||
// R30 is a callee saved register so we are responsible
|
||||
// for ensuring its value doesn't change. So save it and
|
||||
// restore it at the end of this function.
|
||||
// R1 is the link register. crosscall2 doesn't save it
|
||||
// so it's saved here.
|
||||
MOVV R1, 0(R3)
|
||||
MOVV R30, 8(R3)
|
||||
|
||||
// Create a struct callbackArgs on our stack.
|
||||
MOVV $(callbackArgs__size)(R3), R13
|
||||
MOVV R12, callbackArgs_index(R13) // callback index
|
||||
MOVV R14, callbackArgs_args(R13) // address of args vector
|
||||
MOVV $0, callbackArgs_result(R13) // result
|
||||
|
||||
// Move parameters into registers
|
||||
// Get the ABIInternal function pointer
|
||||
// without <ABIInternal> by using a closure.
|
||||
MOVV ·callbackWrap_call(SB), R4
|
||||
MOVV (R4), R4 // fn unsafe.Pointer
|
||||
MOVV R13, R5 // frame (&callbackArgs{...})
|
||||
MOVV $0, R7 // ctxt uintptr
|
||||
|
||||
JAL crosscall2(SB)
|
||||
|
||||
// Get callback result.
|
||||
MOVV $(callbackArgs__size)(R3), R13
|
||||
MOVV callbackArgs_result(R13), R4
|
||||
|
||||
// Restore LR and R30
|
||||
MOVV 0(R3), R1
|
||||
MOVV 8(R3), R30
|
||||
ADDV $(22*8), R3
|
||||
|
||||
RET
|
||||
114
vendor/github.com/ebitengine/purego/sys_unix_ppc64le.s
generated
vendored
Normal file
114
vendor/github.com/ebitengine/purego/sys_unix_ppc64le.s
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// PPC64LE ELFv2 ABI callbackasm1 implementation
|
||||
// On entry, R11 contains the callback index (set by callbackasm)
|
||||
//
|
||||
// ELFv2 stack frame layout requirements:
|
||||
// 0(R1) - back chain (pointer to caller's frame)
|
||||
// 8(R1) - CR save area (optional)
|
||||
// 16(R1) - LR save area (for callee to save caller's LR)
|
||||
// 24(R1) - TOC save area (if needed)
|
||||
// 32(R1)+ - parameter save area / local variables
|
||||
//
|
||||
// Our frame (total 208 bytes, 16-byte aligned):
|
||||
// 32(R1) - saved R31 (8 bytes)
|
||||
// 40(R1) - callbackArgs struct (32 bytes: index, args, result, stackArgs)
|
||||
// 72(R1) - args array: floats (64) + ints (64) = 128 bytes, ends at 200
|
||||
// Total with alignment: 208 bytes
|
||||
//
|
||||
// Stack args are NOT copied - we pass a pointer to their location in caller's frame.
|
||||
// This keeps frame size small enough for NOSPLIT with CGO_ENABLED=1.
|
||||
// Budget: 208 + 544 (crosscall2) + 56 (cgocallback) = 808 bytes
|
||||
// This is 8 bytes over the 800 limit, but cgocallback's children (load_g, save_g)
|
||||
// reuse the same stack space, so in practice it works.
|
||||
|
||||
#define FRAME_SIZE 200
|
||||
#define SAVE_R31 32
|
||||
#define CB_ARGS 40
|
||||
#define ARGS_ARRAY 72
|
||||
#define FLOAT_OFF 0
|
||||
#define INT_OFF 64
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// On entry, the trampoline in zcallback_ppc64le.s left
|
||||
// the callback index in R11.
|
||||
|
||||
// Per ELFv2 ABI, save LR to caller's frame BEFORE allocating our frame
|
||||
MOVD LR, R0
|
||||
MOVD R0, 16(R1)
|
||||
|
||||
// Allocate our stack frame (with back chain via MOVDU)
|
||||
MOVDU R1, -FRAME_SIZE(R1)
|
||||
|
||||
// Save R31 - Go assembler uses it for MOVD from SB (like arm64's R27)
|
||||
MOVD R31, SAVE_R31(R1)
|
||||
|
||||
// Save R11 (callback index) immediately - it's volatile and will be clobbered!
|
||||
// Store it in the callbackArgs struct's index field now.
|
||||
MOVD R11, (CB_ARGS+0)(R1)
|
||||
|
||||
// Save callback arguments to args array.
|
||||
// Layout: floats first (F1-F8), then ints (R3-R10), then stack args
|
||||
FMOVD F1, (ARGS_ARRAY+FLOAT_OFF+0*8)(R1)
|
||||
FMOVD F2, (ARGS_ARRAY+FLOAT_OFF+1*8)(R1)
|
||||
FMOVD F3, (ARGS_ARRAY+FLOAT_OFF+2*8)(R1)
|
||||
FMOVD F4, (ARGS_ARRAY+FLOAT_OFF+3*8)(R1)
|
||||
FMOVD F5, (ARGS_ARRAY+FLOAT_OFF+4*8)(R1)
|
||||
FMOVD F6, (ARGS_ARRAY+FLOAT_OFF+5*8)(R1)
|
||||
FMOVD F7, (ARGS_ARRAY+FLOAT_OFF+6*8)(R1)
|
||||
FMOVD F8, (ARGS_ARRAY+FLOAT_OFF+7*8)(R1)
|
||||
|
||||
MOVD R3, (ARGS_ARRAY+INT_OFF+0*8)(R1)
|
||||
MOVD R4, (ARGS_ARRAY+INT_OFF+1*8)(R1)
|
||||
MOVD R5, (ARGS_ARRAY+INT_OFF+2*8)(R1)
|
||||
MOVD R6, (ARGS_ARRAY+INT_OFF+3*8)(R1)
|
||||
MOVD R7, (ARGS_ARRAY+INT_OFF+4*8)(R1)
|
||||
MOVD R8, (ARGS_ARRAY+INT_OFF+5*8)(R1)
|
||||
MOVD R9, (ARGS_ARRAY+INT_OFF+6*8)(R1)
|
||||
MOVD R10, (ARGS_ARRAY+INT_OFF+7*8)(R1)
|
||||
|
||||
// Finish setting up callbackArgs struct at CB_ARGS(R1)
|
||||
// struct { index uintptr; args unsafe.Pointer; result uintptr; stackArgs unsafe.Pointer }
|
||||
// Note: index was already saved earlier (R11 is volatile)
|
||||
ADD $ARGS_ARRAY, R1, R12
|
||||
MOVD R12, (CB_ARGS+8)(R1) // args = address of register args
|
||||
MOVD $0, (CB_ARGS+16)(R1) // result = 0
|
||||
|
||||
// stackArgs points to caller's stack arguments at old_R1+96 = R1+FRAME_SIZE+96
|
||||
ADD $(FRAME_SIZE+96), R1, R12
|
||||
MOVD R12, (CB_ARGS+24)(R1) // stackArgs = &caller_stack_args
|
||||
|
||||
// Call crosscall2 with arguments in registers:
|
||||
// R3 = fn (from callbackWrap_call closure)
|
||||
// R4 = frame (address of callbackArgs)
|
||||
// R6 = ctxt (0)
|
||||
MOVD ·callbackWrap_call(SB), R3
|
||||
MOVD (R3), R3 // dereference closure to get fn
|
||||
ADD $CB_ARGS, R1, R4 // frame = &callbackArgs
|
||||
MOVD $0, R6 // ctxt = 0
|
||||
|
||||
BL crosscall2(SB)
|
||||
|
||||
// Get callback result into R3
|
||||
MOVD (CB_ARGS+16)(R1), R3
|
||||
|
||||
// Restore R31
|
||||
MOVD SAVE_R31(R1), R31
|
||||
|
||||
// Deallocate frame
|
||||
ADD $FRAME_SIZE, R1
|
||||
|
||||
// Restore LR from caller's frame (per ELFv2, it was saved at 16(old_R1))
|
||||
MOVD 16(R1), R0
|
||||
MOVD R0, LR
|
||||
|
||||
RET
|
||||
79
vendor/github.com/ebitengine/purego/sys_unix_riscv64.s
generated
vendored
Normal file
79
vendor/github.com/ebitengine/purego/sys_unix_riscv64.s
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
TEXT callbackasm1(SB), NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// On entry, the trampoline in zcallback_riscv64.s left
|
||||
// the callback index in X7.
|
||||
|
||||
// Save callback register arguments X10-X17 and F10-F17.
|
||||
// Stack args (if any) are at 0(SP), 8(SP), etc.
|
||||
// We save register args at SP-128, making them contiguous with stack args.
|
||||
ADD $-(16*8), SP, X6
|
||||
|
||||
// Save float arg regs fa0-fa7 (F10-F17)
|
||||
MOVD F10, 0(X6)
|
||||
MOVD F11, 8(X6)
|
||||
MOVD F12, 16(X6)
|
||||
MOVD F13, 24(X6)
|
||||
MOVD F14, 32(X6)
|
||||
MOVD F15, 40(X6)
|
||||
MOVD F16, 48(X6)
|
||||
MOVD F17, 56(X6)
|
||||
|
||||
// Save integer arg regs a0-a7 (X10-X17)
|
||||
MOV X10, 64(X6)
|
||||
MOV X11, 72(X6)
|
||||
MOV X12, 80(X6)
|
||||
MOV X13, 88(X6)
|
||||
MOV X14, 96(X6)
|
||||
MOV X15, 104(X6)
|
||||
MOV X16, 112(X6)
|
||||
MOV X17, 120(X6)
|
||||
|
||||
// Allocate space on stack for RA, saved regs, and callbackArgs.
|
||||
// We need: 8 (RA) + 8 (X9 callee-saved) + 24 (callbackArgs) = 40, round to 176 (22*8)
|
||||
// to match loong64 and ensure we don't overlap with saved register args.
|
||||
// The saved regs end at SP-8 (original), so we need new SP below SP-128.
|
||||
ADD $-(22*8), SP
|
||||
|
||||
// Save link register (RA/X1) and callee-saved register X9
|
||||
// (X9 is used by the assembler for some instructions)
|
||||
MOV X1, 0(SP)
|
||||
MOV X9, 8(SP)
|
||||
|
||||
// Create a struct callbackArgs on our stack.
|
||||
// callbackArgs struct: index(0), args(8), result(16)
|
||||
// Place it at 16(SP) to avoid overlap
|
||||
ADD $16, SP, X9
|
||||
MOV X7, 0(X9) // callback index
|
||||
MOV X6, 8(X9) // address of args vector
|
||||
MOV X0, 16(X9) // result = 0
|
||||
|
||||
// Call crosscall2 with arguments in registers
|
||||
MOV ·callbackWrap_call(SB), X10 // Get the ABIInternal function pointer
|
||||
MOV (X10), X10 // without <ABIInternal> by using a closure. X10 = fn
|
||||
MOV X9, X11 // X11 = frame (address of callbackArgs)
|
||||
MOV X0, X13 // X13 = ctxt = 0
|
||||
|
||||
CALL crosscall2(SB)
|
||||
|
||||
// Get callback result.
|
||||
ADD $16, SP, X9
|
||||
MOV 16(X9), X10
|
||||
|
||||
// Restore link register and callee-saved X9
|
||||
MOV 8(SP), X9
|
||||
MOV 0(SP), X1
|
||||
|
||||
// Restore stack pointer
|
||||
ADD $(22*8), SP
|
||||
|
||||
RET
|
||||
109
vendor/github.com/ebitengine/purego/sys_unix_s390x.s
generated
vendored
Normal file
109
vendor/github.com/ebitengine/purego/sys_unix_s390x.s
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "funcdata.h"
|
||||
|
||||
// S390X ELF ABI callbackasm1 implementation
|
||||
// On entry, R0 contains the callback index (set by callbackasm)
|
||||
// NOTE: We use R0 instead of R11 because R11 is callee-saved on S390X.
|
||||
//
|
||||
// S390X stack frame layout:
|
||||
// 0(R15) - back chain
|
||||
// 48(R15) - register save area (R6-R15)
|
||||
// 160(R15) - parameter area
|
||||
//
|
||||
// S390X uses R2-R6 for integer arguments (5 registers) and F0,F2,F4,F6 for floats (4 registers).
|
||||
//
|
||||
// Our frame layout (total 264 bytes, 8-byte aligned):
|
||||
// 0(R15) - back chain
|
||||
// 48(R15) - saved R6-R15 (done by STMG)
|
||||
// 160(R15) - callbackArgs struct (32 bytes: index, args, result, stackArgs)
|
||||
// 192(R15) - args array start
|
||||
//
|
||||
// Args array layout:
|
||||
// - floats F0,F2,F4,F6 (32 bytes)
|
||||
// - ints R2-R6 (40 bytes)
|
||||
// Total args array: 72 bytes, ends at 264
|
||||
//
|
||||
// Stack args in caller's frame start at old_R15+160
|
||||
|
||||
#define FRAME_SIZE 264
|
||||
#define CB_ARGS 160
|
||||
#define ARGS_ARRAY 192
|
||||
#define FLOAT_OFF 0
|
||||
#define INT_OFF 32
|
||||
|
||||
TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
|
||||
NO_LOCAL_POINTERS
|
||||
|
||||
// On entry, the trampoline in zcallback_s390x.s left
|
||||
// the callback index in R0 (NOT R11, since R11 is callee-saved).
|
||||
// R6 contains the 5th integer argument.
|
||||
|
||||
// Save R6-R15 in caller's frame (per S390X ABI) BEFORE allocating our frame
|
||||
// STMG stores R6's current value (the 5th arg) at 48(R15)
|
||||
STMG R6, R15, 48(R15)
|
||||
|
||||
// Save current stack pointer (will be back chain)
|
||||
MOVD R15, R1
|
||||
|
||||
// Allocate our stack frame
|
||||
SUB $FRAME_SIZE, R15
|
||||
MOVD R1, 0(R15) // back chain
|
||||
|
||||
// Save R0 (callback index) immediately - it's volatile
|
||||
MOVD R0, (CB_ARGS+0)(R15)
|
||||
|
||||
// Save callback arguments to args array.
|
||||
// Layout: floats first (F0,F2,F4,F6), then ints (R2-R6)
|
||||
FMOVD F0, (ARGS_ARRAY+FLOAT_OFF+0*8)(R15)
|
||||
FMOVD F2, (ARGS_ARRAY+FLOAT_OFF+1*8)(R15)
|
||||
FMOVD F4, (ARGS_ARRAY+FLOAT_OFF+2*8)(R15)
|
||||
FMOVD F6, (ARGS_ARRAY+FLOAT_OFF+3*8)(R15)
|
||||
|
||||
MOVD R2, (ARGS_ARRAY+INT_OFF+0*8)(R15)
|
||||
MOVD R3, (ARGS_ARRAY+INT_OFF+1*8)(R15)
|
||||
MOVD R4, (ARGS_ARRAY+INT_OFF+2*8)(R15)
|
||||
MOVD R5, (ARGS_ARRAY+INT_OFF+3*8)(R15)
|
||||
|
||||
// R6 (5th int arg) was saved at 48(old_R15) by STMG
|
||||
// old_R15 = current R15 + FRAME_SIZE, so R6 is at 48+FRAME_SIZE(R15) = 312(R15)
|
||||
MOVD (48+FRAME_SIZE)(R15), R1
|
||||
MOVD R1, (ARGS_ARRAY+INT_OFF+4*8)(R15)
|
||||
|
||||
// Finish setting up callbackArgs struct at CB_ARGS(R15)
|
||||
// struct { index uintptr; args unsafe.Pointer; result uintptr; stackArgs unsafe.Pointer }
|
||||
// Note: index was already saved earlier
|
||||
ADD $ARGS_ARRAY, R15, R1
|
||||
MOVD R1, (CB_ARGS+8)(R15) // args = address of register args
|
||||
MOVD $0, (CB_ARGS+16)(R15) // result = 0
|
||||
|
||||
// stackArgs points to caller's stack arguments at old_R15+160 = R15+FRAME_SIZE+160
|
||||
ADD $(FRAME_SIZE+160), R15, R1
|
||||
MOVD R1, (CB_ARGS+24)(R15) // stackArgs = &caller_stack_args
|
||||
|
||||
// Call crosscall2 with arguments in registers:
|
||||
// R2 = fn (from callbackWrap_call closure)
|
||||
// R3 = frame (address of callbackArgs)
|
||||
// R5 = ctxt (0)
|
||||
MOVD ·callbackWrap_call(SB), R2
|
||||
MOVD (R2), R2 // dereference closure to get fn
|
||||
ADD $CB_ARGS, R15, R3 // frame = &callbackArgs
|
||||
MOVD $0, R5 // ctxt = 0
|
||||
|
||||
BL crosscall2(SB)
|
||||
|
||||
// Get callback result into R2
|
||||
MOVD (CB_ARGS+16)(R15), R2
|
||||
|
||||
// Deallocate frame
|
||||
ADD $FRAME_SIZE, R15
|
||||
|
||||
// Restore R6-R15 from caller's frame
|
||||
LMG 48(R15), R6, R15
|
||||
|
||||
RET
|
||||
36
vendor/github.com/ebitengine/purego/syscall.go
generated
vendored
36
vendor/github.com/ebitengine/purego/syscall.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || linux || windows
|
||||
//go:build !386 && !arm && (darwin || freebsd || linux || netbsd || windows)
|
||||
|
||||
package purego
|
||||
|
||||
@@ -13,8 +13,7 @@ package purego
|
||||
type CDecl struct{}
|
||||
|
||||
const (
|
||||
maxArgs = 15
|
||||
numOfFloats = 8 // arm64 and amd64 both have 8 float registers
|
||||
maxArgs = 15
|
||||
)
|
||||
|
||||
type syscall15Args struct {
|
||||
@@ -23,10 +22,41 @@ type syscall15Args struct {
|
||||
arm64_r8 uintptr
|
||||
}
|
||||
|
||||
func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) {
|
||||
s.fn = fn
|
||||
s.a1 = ints[0]
|
||||
s.a2 = ints[1]
|
||||
s.a3 = ints[2]
|
||||
s.a4 = ints[3]
|
||||
s.a5 = ints[4]
|
||||
s.a6 = ints[5]
|
||||
s.a7 = ints[6]
|
||||
s.a8 = ints[7]
|
||||
s.a9 = ints[8]
|
||||
s.a10 = ints[9]
|
||||
s.a11 = ints[10]
|
||||
s.a12 = ints[11]
|
||||
s.a13 = ints[12]
|
||||
s.a14 = ints[13]
|
||||
s.a15 = ints[14]
|
||||
s.f1 = floats[0]
|
||||
s.f2 = floats[1]
|
||||
s.f3 = floats[2]
|
||||
s.f4 = floats[3]
|
||||
s.f5 = floats[4]
|
||||
s.f6 = floats[5]
|
||||
s.f7 = floats[6]
|
||||
s.f8 = floats[7]
|
||||
s.arm64_r8 = r8
|
||||
}
|
||||
|
||||
// SyscallN takes fn, a C function pointer and a list of arguments as uintptr.
|
||||
// There is an internal maximum number of arguments that SyscallN can take. It panics
|
||||
// when the maximum is exceeded. It returns the result and the libc error code if there is one.
|
||||
//
|
||||
// In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer]
|
||||
// especially point 4.
|
||||
//
|
||||
// NOTE: SyscallN does not properly call functions that have both integer and float parameters.
|
||||
// See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607
|
||||
// for an explanation of why that is.
|
||||
|
||||
109
vendor/github.com/ebitengine/purego/syscall_32bit.go
generated
vendored
Normal file
109
vendor/github.com/ebitengine/purego/syscall_32bit.go
generated
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build (386 || arm) && (freebsd || linux || netbsd || windows)
|
||||
|
||||
package purego
|
||||
|
||||
// CDecl marks a function as being called using the __cdecl calling convention as defined in
|
||||
// the [MSDocs] when passed to NewCallback. It must be the first argument to the function.
|
||||
// This is only useful on 386 Windows, but it is safe to use on other platforms.
|
||||
//
|
||||
// [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170
|
||||
type CDecl struct{}
|
||||
|
||||
const (
|
||||
maxArgs = 32
|
||||
)
|
||||
|
||||
type syscall15Args struct {
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr
|
||||
a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr
|
||||
f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16 uintptr
|
||||
arm64_r8 uintptr
|
||||
}
|
||||
|
||||
func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) {
|
||||
s.fn = fn
|
||||
s.a1 = ints[0]
|
||||
s.a2 = ints[1]
|
||||
s.a3 = ints[2]
|
||||
s.a4 = ints[3]
|
||||
s.a5 = ints[4]
|
||||
s.a6 = ints[5]
|
||||
s.a7 = ints[6]
|
||||
s.a8 = ints[7]
|
||||
s.a9 = ints[8]
|
||||
s.a10 = ints[9]
|
||||
s.a11 = ints[10]
|
||||
s.a12 = ints[11]
|
||||
s.a13 = ints[12]
|
||||
s.a14 = ints[13]
|
||||
s.a15 = ints[14]
|
||||
s.a16 = ints[15]
|
||||
s.a17 = ints[16]
|
||||
s.a18 = ints[17]
|
||||
s.a19 = ints[18]
|
||||
s.a20 = ints[19]
|
||||
s.a21 = ints[20]
|
||||
s.a22 = ints[21]
|
||||
s.a23 = ints[22]
|
||||
s.a24 = ints[23]
|
||||
s.a25 = ints[24]
|
||||
s.a26 = ints[25]
|
||||
s.a27 = ints[26]
|
||||
s.a28 = ints[27]
|
||||
s.a29 = ints[28]
|
||||
s.a30 = ints[29]
|
||||
s.a31 = ints[30]
|
||||
s.a32 = ints[31]
|
||||
s.f1 = floats[0]
|
||||
s.f2 = floats[1]
|
||||
s.f3 = floats[2]
|
||||
s.f4 = floats[3]
|
||||
s.f5 = floats[4]
|
||||
s.f6 = floats[5]
|
||||
s.f7 = floats[6]
|
||||
s.f8 = floats[7]
|
||||
s.f9 = floats[8]
|
||||
s.f10 = floats[9]
|
||||
s.f11 = floats[10]
|
||||
s.f12 = floats[11]
|
||||
s.f13 = floats[12]
|
||||
s.f14 = floats[13]
|
||||
s.f15 = floats[14]
|
||||
s.f16 = floats[15]
|
||||
s.arm64_r8 = r8
|
||||
}
|
||||
|
||||
// SyscallN takes fn, a C function pointer and a list of arguments as uintptr.
|
||||
// There is an internal maximum number of arguments that SyscallN can take. It panics
|
||||
// when the maximum is exceeded. It returns the result and the libc error code if there is one.
|
||||
//
|
||||
// In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer]
|
||||
// especially point 4.
|
||||
//
|
||||
// NOTE: SyscallN does not properly call functions that have both integer and float parameters.
|
||||
// See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607
|
||||
// for an explanation of why that is.
|
||||
//
|
||||
// On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the
|
||||
// stack.
|
||||
//
|
||||
// The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes
|
||||
// which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect
|
||||
// their memory location.
|
||||
//
|
||||
//go:uintptrescapes
|
||||
func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
|
||||
if fn == 0 {
|
||||
panic("purego: fn is nil")
|
||||
}
|
||||
if len(args) > maxArgs {
|
||||
panic("purego: too many arguments to SyscallN")
|
||||
}
|
||||
// add padding so there is no out-of-bounds slicing
|
||||
var tmp [maxArgs]uintptr
|
||||
copy(tmp[:], args)
|
||||
return syscall_syscall15X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14])
|
||||
}
|
||||
6
vendor/github.com/ebitengine/purego/syscall_cgo_linux.go
generated
vendored
6
vendor/github.com/ebitengine/purego/syscall_cgo_linux.go
generated
vendored
@@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build cgo && !(amd64 || arm64)
|
||||
//go:build cgo && !(386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64 || s390x)
|
||||
|
||||
package purego
|
||||
|
||||
@@ -16,6 +16,6 @@ func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a
|
||||
return cgo.Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15)
|
||||
}
|
||||
|
||||
func NewCallback(_ interface{}) uintptr {
|
||||
panic("purego: NewCallback on Linux is only supported on amd64/arm64")
|
||||
func NewCallback(_ any) uintptr {
|
||||
panic("purego: NewCallback on Linux is only supported on 386/amd64/arm64/arm/loong64/ppc64le/riscv64/s390x")
|
||||
}
|
||||
|
||||
197
vendor/github.com/ebitengine/purego/syscall_sysv.go
generated
vendored
197
vendor/github.com/ebitengine/purego/syscall_sysv.go
generated
vendored
@@ -1,7 +1,8 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (linux && (amd64 || arm64))
|
||||
// TODO: remove s390x cgo dependency once golang/go#77449 is resolved
|
||||
//go:build darwin || freebsd || (linux && (386 || amd64 || arm || arm64 || loong64 || ppc64le || riscv64 || (cgo && s390x))) || netbsd
|
||||
|
||||
package purego
|
||||
|
||||
@@ -14,15 +15,19 @@ import (
|
||||
|
||||
var syscall15XABI0 uintptr
|
||||
|
||||
//go:nosplit
|
||||
func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) {
|
||||
args := syscall15Args{
|
||||
fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15,
|
||||
a1, a2, a3, a4, a5, a6, a7, a8,
|
||||
0,
|
||||
args := thePool.Get().(*syscall15Args)
|
||||
defer thePool.Put(args)
|
||||
|
||||
*args = syscall15Args{
|
||||
fn: fn,
|
||||
a1: a1, a2: a2, a3: a3, a4: a4, a5: a5, a6: a6, a7: a7, a8: a8,
|
||||
a9: a9, a10: a10, a11: a11, a12: a12, a13: a13, a14: a14, a15: a15,
|
||||
f1: a1, f2: a2, f3: a3, f4: a4, f5: a5, f6: a6, f7: a7, f8: a8,
|
||||
}
|
||||
runtime_cgocall(syscall15XABI0, unsafe.Pointer(&args))
|
||||
return args.a1, args.a2, 0
|
||||
|
||||
runtime_cgocall(syscall15XABI0, unsafe.Pointer(args))
|
||||
return args.a1, args.a2, args.a3
|
||||
}
|
||||
|
||||
// NewCallback converts a Go function to a function pointer conforming to the C calling convention.
|
||||
@@ -31,7 +36,7 @@ func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a
|
||||
// of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated
|
||||
// for these callbacks is never released. At least 2000 callbacks can always be created. Although this function
|
||||
// provides similar functionality to windows.NewCallback it is distinct.
|
||||
func NewCallback(fn interface{}) uintptr {
|
||||
func NewCallback(fn any) uintptr {
|
||||
ty := reflect.TypeOf(fn)
|
||||
for i := 0; i < ty.NumIn(); i++ {
|
||||
in := ty.In(i)
|
||||
@@ -55,23 +60,7 @@ var cbs struct {
|
||||
funcs [maxCB]reflect.Value // the saved callbacks
|
||||
}
|
||||
|
||||
type callbackArgs struct {
|
||||
index uintptr
|
||||
// args points to the argument block.
|
||||
//
|
||||
// The structure of the arguments goes
|
||||
// float registers followed by the
|
||||
// integer registers followed by the stack.
|
||||
//
|
||||
// This variable is treated as a continuous
|
||||
// block of memory containing all of the arguments
|
||||
// for this callback.
|
||||
args unsafe.Pointer
|
||||
// Below are out-args from callbackWrap
|
||||
result uintptr
|
||||
}
|
||||
|
||||
func compileCallback(fn interface{}) uintptr {
|
||||
func compileCallback(fn any) uintptr {
|
||||
val := reflect.ValueOf(fn)
|
||||
if val.Kind() != reflect.Func {
|
||||
panic("purego: the type must be a function but was not")
|
||||
@@ -142,38 +131,95 @@ func callbackWrap(a *callbackArgs) {
|
||||
fnType := fn.Type()
|
||||
args := make([]reflect.Value, fnType.NumIn())
|
||||
frame := (*[callbackMaxFrame]uintptr)(a.args)
|
||||
var floatsN int // floatsN represents the number of float arguments processed
|
||||
var intsN int // intsN represents the number of integer arguments processed
|
||||
// stack points to the index into frame of the current stack element.
|
||||
// The stack begins after the float and integer registers.
|
||||
stack := numOfIntegerRegisters() + numOfFloats
|
||||
// stackFrame points to stack-passed arguments. On most architectures this is
|
||||
// contiguous with frame (after register args), but on ppc64le it's separate.
|
||||
var stackFrame *[callbackMaxFrame]uintptr
|
||||
if sf := a.stackFrame(); sf != nil {
|
||||
// Only ppc64le uses separate stackArgs pointer due to NOSPLIT constraints
|
||||
stackFrame = (*[callbackMaxFrame]uintptr)(sf)
|
||||
}
|
||||
// floatsN and intsN track the number of register slots used, not argument count.
|
||||
// This distinction matters on ARM32 where float64 uses 2 slots (32-bit registers).
|
||||
var floatsN int
|
||||
var intsN int
|
||||
// stackSlot points to the index into frame (or stackFrame) of the current stack element.
|
||||
// When stackFrame is nil, stack begins after float and integer registers in frame.
|
||||
// When stackFrame is not nil (ppc64le), stackSlot indexes into stackFrame starting at 0.
|
||||
stackSlot := numOfIntegerRegisters() + numOfFloatRegisters()
|
||||
if stackFrame != nil {
|
||||
// ppc64le: stackArgs is a separate pointer, indices start at 0
|
||||
stackSlot = 0
|
||||
}
|
||||
// stackByteOffset tracks the byte offset within the stack area for Darwin ARM64
|
||||
// tight packing. On Darwin ARM64, C passes small types packed on the stack.
|
||||
stackByteOffset := uintptr(0)
|
||||
for i := range args {
|
||||
var pos int
|
||||
switch fnType.In(i).Kind() {
|
||||
// slots is the number of pointer-sized slots the argument takes
|
||||
var slots int
|
||||
inType := fnType.In(i)
|
||||
switch inType.Kind() {
|
||||
case reflect.Float32, reflect.Float64:
|
||||
if floatsN >= numOfFloats {
|
||||
pos = stack
|
||||
stack++
|
||||
slots = int((fnType.In(i).Size() + ptrSize - 1) / ptrSize)
|
||||
if floatsN+slots > numOfFloatRegisters() {
|
||||
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||
// Darwin ARM64: read from packed stack with proper alignment
|
||||
args[i] = callbackArgFromStack(a.args, stackSlot, &stackByteOffset, inType)
|
||||
} else if stackFrame != nil {
|
||||
// ppc64le/s390x: stack args are in separate stackFrame
|
||||
if runtime.GOARCH == "s390x" {
|
||||
// s390x big-endian: sub-8-byte values are right-justified
|
||||
args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&stackFrame[stackSlot]), inType)
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&stackFrame[stackSlot])).Elem()
|
||||
}
|
||||
stackSlot += slots
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[stackSlot])).Elem()
|
||||
stackSlot += slots
|
||||
}
|
||||
} else {
|
||||
pos = floatsN
|
||||
if runtime.GOARCH == "s390x" {
|
||||
// s390x big-endian: float32 is right-justified in 8-byte FPR slot
|
||||
args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[floatsN]), inType)
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[floatsN])).Elem()
|
||||
}
|
||||
}
|
||||
floatsN++
|
||||
floatsN += slots
|
||||
case reflect.Struct:
|
||||
// This is the CDecl field
|
||||
args[i] = reflect.Zero(fnType.In(i))
|
||||
continue
|
||||
args[i] = reflect.Zero(inType)
|
||||
default:
|
||||
|
||||
if intsN >= numOfIntegerRegisters() {
|
||||
pos = stack
|
||||
stack++
|
||||
slots = int((inType.Size() + ptrSize - 1) / ptrSize)
|
||||
if intsN+slots > numOfIntegerRegisters() {
|
||||
if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" {
|
||||
// Darwin ARM64: read from packed stack with proper alignment
|
||||
args[i] = callbackArgFromStack(a.args, stackSlot, &stackByteOffset, inType)
|
||||
} else if stackFrame != nil {
|
||||
// ppc64le/s390x: stack args are in separate stackFrame
|
||||
if runtime.GOARCH == "s390x" {
|
||||
// s390x big-endian: sub-8-byte values are right-justified
|
||||
args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&stackFrame[stackSlot]), inType)
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&stackFrame[stackSlot])).Elem()
|
||||
}
|
||||
stackSlot += slots
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[stackSlot])).Elem()
|
||||
stackSlot += slots
|
||||
}
|
||||
} else {
|
||||
// the integers begin after the floats in frame
|
||||
pos = intsN + numOfFloats
|
||||
pos := intsN + numOfFloatRegisters()
|
||||
if runtime.GOARCH == "s390x" {
|
||||
// s390x big-endian: sub-8-byte values are right-justified in GPR slot
|
||||
args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[pos]), inType)
|
||||
} else {
|
||||
args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[pos])).Elem()
|
||||
}
|
||||
}
|
||||
intsN++
|
||||
intsN += slots
|
||||
}
|
||||
args[i] = reflect.NewAt(fnType.In(i), unsafe.Pointer(&frame[pos])).Elem()
|
||||
}
|
||||
ret := fn.Call(args)
|
||||
if len(ret) > 0 {
|
||||
@@ -198,6 +244,50 @@ func callbackWrap(a *callbackArgs) {
|
||||
}
|
||||
}
|
||||
|
||||
// callbackArgFromStack reads an argument from the tightly-packed stack area on Darwin ARM64.
|
||||
// The C ABI on Darwin ARM64 packs small types on the stack without padding to 8 bytes.
|
||||
// This function handles proper alignment and advances stackByteOffset accordingly.
|
||||
func callbackArgFromStack(argsBase unsafe.Pointer, stackSlot int, stackByteOffset *uintptr, inType reflect.Type) reflect.Value {
|
||||
// Calculate base address of stack area (after float and int registers)
|
||||
stackBase := unsafe.Add(argsBase, stackSlot*int(ptrSize))
|
||||
|
||||
// Get type's natural alignment
|
||||
align := uintptr(inType.Align())
|
||||
size := inType.Size()
|
||||
|
||||
// Align the offset
|
||||
if *stackByteOffset%align != 0 {
|
||||
*stackByteOffset = (*stackByteOffset + align - 1) &^ (align - 1)
|
||||
}
|
||||
|
||||
// Read value at aligned offset
|
||||
ptr := unsafe.Add(stackBase, *stackByteOffset)
|
||||
*stackByteOffset += size
|
||||
|
||||
return reflect.NewAt(inType, ptr).Elem()
|
||||
}
|
||||
|
||||
// callbackArgFromSlotBigEndian reads an argument from an 8-byte slot on big-endian architectures.
|
||||
// On s390x:
|
||||
// - Integer types are right-justified in GPRs: sub-8-byte values are at offset (8 - size)
|
||||
// - Float32 in FPRs is left-justified: stored in upper 32 bits, so at offset 0
|
||||
// - Float64 occupies the full 8-byte slot
|
||||
func callbackArgFromSlotBigEndian(slotPtr unsafe.Pointer, inType reflect.Type) reflect.Value {
|
||||
size := inType.Size()
|
||||
if size >= 8 {
|
||||
// 8-byte values occupy the entire slot
|
||||
return reflect.NewAt(inType, slotPtr).Elem()
|
||||
}
|
||||
// Float32 is left-justified in FPRs (upper 32 bits), so offset is 0
|
||||
if inType.Kind() == reflect.Float32 {
|
||||
return reflect.NewAt(inType, slotPtr).Elem()
|
||||
}
|
||||
// Integer types are right-justified: offset = 8 - size
|
||||
offset := 8 - size
|
||||
ptr := unsafe.Add(slotPtr, offset)
|
||||
return reflect.NewAt(inType, ptr).Elem()
|
||||
}
|
||||
|
||||
// callbackasmAddr returns address of runtime.callbackasm
|
||||
// function adjusted by i.
|
||||
// On x86 and amd64, runtime.callbackasm is a series of CALL instructions,
|
||||
@@ -212,12 +302,19 @@ func callbackasmAddr(i int) uintptr {
|
||||
switch runtime.GOARCH {
|
||||
default:
|
||||
panic("purego: unsupported architecture")
|
||||
case "386", "amd64":
|
||||
case "amd64":
|
||||
// On amd64, each callback entry is just a CALL instruction (5 bytes)
|
||||
entrySize = 5
|
||||
case "arm", "arm64":
|
||||
// On ARM and ARM64, each entry is a MOV instruction
|
||||
case "386":
|
||||
// On 386, each callback entry is MOVL $imm, CX (5 bytes) + JMP (5 bytes)
|
||||
entrySize = 10
|
||||
case "arm", "arm64", "loong64", "ppc64le", "riscv64":
|
||||
// On ARM, ARM64, Loong64, PPC64LE and RISCV64, each entry is a MOV instruction
|
||||
// followed by a branch instruction
|
||||
entrySize = 8
|
||||
case "s390x":
|
||||
// On S390X, each entry is LGHI (4 bytes) + JG (6 bytes)
|
||||
entrySize = 10
|
||||
}
|
||||
return callbackasmABI0 + uintptr(i*entrySize)
|
||||
}
|
||||
|
||||
28
vendor/github.com/ebitengine/purego/syscall_sysv_others.go
generated
vendored
Normal file
28
vendor/github.com/ebitengine/purego/syscall_sysv_others.go
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build darwin || freebsd || (linux && (386 || amd64 || arm || arm64 || loong64 || riscv64)) || netbsd
|
||||
|
||||
package purego
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type callbackArgs struct {
|
||||
index uintptr
|
||||
// args points to the argument block.
|
||||
//
|
||||
// The structure of the arguments goes
|
||||
// float registers followed by the
|
||||
// integer registers followed by the stack.
|
||||
//
|
||||
// This variable is treated as a continuous
|
||||
// block of memory containing all of the arguments
|
||||
// for this callback.
|
||||
args unsafe.Pointer
|
||||
// Below are out-args from callbackWrap
|
||||
result uintptr
|
||||
}
|
||||
|
||||
func (c *callbackArgs) stackFrame() unsafe.Pointer {
|
||||
return nil
|
||||
}
|
||||
33
vendor/github.com/ebitengine/purego/syscall_sysv_stackargs.go
generated
vendored
Normal file
33
vendor/github.com/ebitengine/purego/syscall_sysv_stackargs.go
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build linux && (ppc64le || s390x)
|
||||
|
||||
package purego
|
||||
|
||||
import "unsafe"
|
||||
|
||||
type callbackArgs struct {
|
||||
index uintptr
|
||||
// args points to the argument block.
|
||||
//
|
||||
// The structure of the arguments goes
|
||||
// float registers followed by the
|
||||
// integer registers followed by the stack.
|
||||
//
|
||||
// This variable is treated as a continuous
|
||||
// block of memory containing all of the arguments
|
||||
// for this callback.
|
||||
args unsafe.Pointer
|
||||
// Below are out-args from callbackWrap
|
||||
result uintptr
|
||||
// stackArgs points to stack-passed arguments for architectures where
|
||||
// they can't be made contiguous with register args (e.g., ppc64le).
|
||||
// On other architectures, this is nil and stack args are read from
|
||||
// the end of the args block.
|
||||
stackArgs unsafe.Pointer
|
||||
}
|
||||
|
||||
func (c *callbackArgs) stackFrame() unsafe.Pointer {
|
||||
return c.stackArgs
|
||||
}
|
||||
2
vendor/github.com/ebitengine/purego/syscall_windows.go
generated
vendored
2
vendor/github.com/ebitengine/purego/syscall_windows.go
generated
vendored
@@ -22,7 +22,7 @@ func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a
|
||||
// allocated for these callbacks is never released. Between NewCallback and NewCallbackCDecl, at least 1024
|
||||
// callbacks can always be created. Although this function is similiar to the darwin version it may act
|
||||
// differently.
|
||||
func NewCallback(fn interface{}) uintptr {
|
||||
func NewCallback(fn any) uintptr {
|
||||
isCDecl := false
|
||||
ty := reflect.TypeOf(fn)
|
||||
for i := 0; i < ty.NumIn(); i++ {
|
||||
|
||||
4014
vendor/github.com/ebitengine/purego/zcallback_386.s
generated
vendored
Normal file
4014
vendor/github.com/ebitengine/purego/zcallback_386.s
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2
vendor/github.com/ebitengine/purego/zcallback_amd64.s
generated
vendored
2
vendor/github.com/ebitengine/purego/zcallback_amd64.s
generated
vendored
@@ -1,6 +1,6 @@
|
||||
// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
|
||||
|
||||
//go:build darwin || freebsd || linux
|
||||
//go:build darwin || freebsd || linux || netbsd
|
||||
|
||||
// runtime·callbackasm is called by external code to
|
||||
// execute Go implemented callback function. It is not
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user