arch/info.go (133 lines of code) (raw):
// Licensed to Elasticsearch B.V. under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Elasticsearch B.V. licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
package arch
import (
"fmt"
"runtime"
"strings"
)
// Info contains Linux architecture information (name, audit arch, and syscall
// tables).
type Info struct {
Name string // Linux architecture name (not necessarily the GOARCH name).
ID AuditArch // Linux audit architecture constant.
SyscallNames map[string]int // Mapping of syscall names to numbers.
SyscallNumbers map[int]string // Mapping of syscall numbers to names.
SeccompMask int // A mask to apply to syscall numbers in BPF instructions (e.g. X32_SYSCALL_BIT).
}
// Linux architecture types.
var (
ARM = &Info{
Name: "arm",
ID: auditArchARM,
SyscallNumbers: syscallsARM,
SyscallNames: invert(syscallsARM),
}
AARCH64 = &Info{
Name: "aarch64",
ID: auditArchAARCH64,
SyscallNumbers: syscallsAARCH64,
SyscallNames: invert(syscallsAARCH64),
}
I386 = &Info{
Name: "i386",
ID: auditArchI386,
SyscallNumbers: syscalls386,
SyscallNames: invert(syscalls386),
}
X32 = &Info{
// Not a valid GOARCH, but an amd64 binary can use the 32-bit ABI so
// this can be used to specify those syscalls.
Name: "x32",
ID: auditArchX86_64,
SeccompMask: x32SyscallMask,
SyscallNumbers: syscallsX32,
SyscallNames: invert(syscallsX32),
}
X86_64 = &Info{
Name: "x86_64",
ID: auditArchX86_64,
SyscallNumbers: syscallsX86_64,
SyscallNames: invert(syscallsX86_64),
}
// The following architectures are not fully implemented. Syscall tables
// need to be added for them (syscall number -> name mapping).
PPC = &Info{
Name: "ppc",
ID: auditArchPPC,
}
PPC64 = &Info{
Name: "ppc64",
ID: auditArchPPC64,
}
PPC64LE = &Info{
Name: "ppc64le",
ID: auditArchPPC64LE,
}
S390 = &Info{
Name: "s390",
ID: auditArchS390,
}
S390X = &Info{
Name: "s390x",
ID: auditArchS390X,
}
MIPS = &Info{
Name: "mips",
ID: auditArchMIPS,
}
MIPSEL = &Info{
Name: "mipsel",
ID: auditArchMIPSEL,
}
MIPS64 = &Info{
Name: "mips64",
ID: auditArchMIPS64,
}
MIPS64N32 = &Info{
Name: "mips64n32",
ID: auditArchMIPS64N32,
}
MIPSEL64 = &Info{
Name: "mipsel64",
ID: auditArchMIPSEL64,
}
MIPSEL64N32 = &Info{
Name: "mipsel64n32",
ID: auditArchMIPSEL64N32,
}
)
// invert a map[int]string to map[string]int.
func invert(in map[int]string) map[string]int {
out := make(map[string]int, len(in))
for k, v := range in {
out[v] = k
}
return out
}
// arches is a mapping of GOARCH and Linux arch names to architecture related
// information.
var arches = map[string]*Info{
"arm": ARM,
"ppc": PPC,
"ppc64": PPC64,
"ppc64le": PPC64LE,
"s390": S390,
"s390x": S390X,
"mips": MIPS,
"mipsle": MIPSEL,
"mips64": MIPS64,
"i386": I386,
"386": I386,
"x32": X32,
"x86_64": X86_64,
"amd64": X86_64,
"aarch64": AARCH64,
"arm64": AARCH64,
"mips64n32": MIPS64N32,
"mips64p32": MIPS64N32,
"mipsel64": MIPSEL64,
"mips64le": MIPSEL64,
"mipsel64n32": MIPSEL64N32,
"mips64p32le": MIPSEL64N32,
}
// GetInfo returns the arch Info associated with the given architecture name.
// If an architecture is not fully implemented it will return an error.
func GetInfo(name string) (*Info, error) {
if name == "" {
name = runtime.GOARCH
} else {
name = strings.ToLower(name)
}
arch, found := arches[name]
if !found || len(arch.SyscallNames) == 0 {
return nil, fmt.Errorf("unsupported arch: %v", name)
}
return arch, nil
}