Skip to content

Commit b68699b

Browse files
strophyzeroshade
andauthored
fix: runtime.staticuint64s+42100384 is not 2-byte aligned on big-endian (#1194)
https://github.com/minio/warp recently added iceberg-go as a dependency. iceberg-go encounters the following compiler error on s390x architecture (big-endian) during packaging for Alpine Linux: ``` # github.com/minio/warp github.com/apache/iceberg-go/table/internal.newStatAgg[go.shape.bool]: runtime.staticuint64s+42100384 is not 2-byte aligned github.com/apache/iceberg-go/table/internal.newStatAgg[go.shape.bool]: runtime.staticuint64s+42100384 is not 2-byte aligned github.com/apache/iceberg-go.getComparator[go.shape.bool]: runtime.staticuint64s+42100384 is not 2-byte aligned github.com/apache/iceberg-go.getComparator[go.shape.bool]: runtime.staticuint64s+42100384 is not 2-byte aligned >>> ERROR: warp-s3: build failed ``` The issue here is instantiating the generic bool comparator on a generic zero value, resulting in an alignment bug on big-endian architecture. This fix replaces the generic zero-value comparator initialization with explicit typed comparators, allowing compilation on s390x. Co-authored-by: Matt Topol <matt@columnar.tech>
1 parent 846e395 commit b68699b

2 files changed

Lines changed: 61 additions & 30 deletions

File tree

.github/workflows/go-ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,28 @@ jobs:
6060
# Race detector is opt-in per package/test.
6161
- name: Run race detector
6262
run: go test -race -v ./codec/...
63+
64+
# Guards against big-endian-only failures such as the runtime.staticuint64s
65+
# relocation misalignment triggered by boxing scalars in generic code
66+
# (golang/go#76744). The fault is a linker error and only s390x's linker
67+
# rejects the misaligned relocation, so this must build a main package for
68+
# s390x specifically rather than just vet or compile libraries.
69+
cross-compile:
70+
name: cross-compile linux/s390x
71+
runs-on: ubuntu-latest
72+
steps:
73+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
74+
with:
75+
persist-credentials: false
76+
- name: Install Go
77+
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
78+
with:
79+
go-version: '1.26.1'
80+
cache: true
81+
cache-dependency-path: go.sum
82+
- name: Build for big-endian (s390x)
83+
env:
84+
GOOS: linux
85+
GOARCH: s390x
86+
CGO_ENABLED: '0'
87+
run: go build ./...

literals.go

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -80,37 +80,43 @@ type NumericLiteral interface {
8080
Decrement() Literal
8181
}
8282

83-
// NewLiteral provides a literal based on the type of T
83+
// NewLiteral provides a literal based on the type of T.
84+
//
85+
// The type switch is performed on &val (a pointer) rather than val itself.
86+
// Boxing a small scalar such as bool into an interface makes the compiler
87+
// reference runtime.staticuint64s, which emits a relocation the linker rejects
88+
// as misaligned on big-endian platforms such as s390x. Switching on a pointer
89+
// boxes only the pointer, never the scalar, avoiding that reference.
8490
func NewLiteral[T LiteralType](val T) Literal {
85-
switch v := any(val).(type) {
86-
case bool:
87-
return BoolLiteral(v)
88-
case int32:
89-
return Int32Literal(v)
90-
case int64:
91-
return Int64Literal(v)
92-
case float32:
93-
return Float32Literal(v)
94-
case float64:
95-
return Float64Literal(v)
96-
case Date:
97-
return DateLiteral(v)
98-
case Time:
99-
return TimeLiteral(v)
100-
case Timestamp:
101-
return TimestampLiteral(v)
102-
case TimestampNano:
103-
return TimestampNsLiteral(v)
104-
case string:
105-
return StringLiteral(v)
106-
case []byte:
107-
return BinaryLiteral(v)
108-
case uuid.UUID:
109-
return UUIDLiteral(v)
110-
case Decimal:
111-
return DecimalLiteral(v)
112-
case variant.Value:
113-
return VariantLiteral(v)
91+
switch v := any(&val).(type) {
92+
case *bool:
93+
return BoolLiteral(*v)
94+
case *int32:
95+
return Int32Literal(*v)
96+
case *int64:
97+
return Int64Literal(*v)
98+
case *float32:
99+
return Float32Literal(*v)
100+
case *float64:
101+
return Float64Literal(*v)
102+
case *Date:
103+
return DateLiteral(*v)
104+
case *Time:
105+
return TimeLiteral(*v)
106+
case *Timestamp:
107+
return TimestampLiteral(*v)
108+
case *TimestampNano:
109+
return TimestampNsLiteral(*v)
110+
case *string:
111+
return StringLiteral(*v)
112+
case *[]byte:
113+
return BinaryLiteral(*v)
114+
case *uuid.UUID:
115+
return UUIDLiteral(*v)
116+
case *Decimal:
117+
return DecimalLiteral(*v)
118+
case *variant.Value:
119+
return VariantLiteral(*v)
114120
}
115121
panic("can't happen due to literal type constraint")
116122
}

0 commit comments

Comments
 (0)