func buildARM()

in arch/mk_syscalls_linux.go [97:167]


func buildARM(dir string) (*Arch, error) {
	const (
		tablePath  = "/arch/arm/tools/syscall.tbl"
		headerPath = "/arch/arm/include/uapi/asm/unistd.h" // ARM private syscalls.
		armNrBase  = 0x0f0000                              // Base value for ARM private syscalls.
	)

	syscallsA, err := readSyscalls(tablePath, dir, func(line string) (*Syscall, error) {
		if len(line) == 0 || strings.HasPrefix(line, "#") {
			return nil, nil
		}

		fields := strings.Fields(line)
		if len(fields) < 3 {
			return nil, fmt.Errorf("unexpected line format: %v", line)
		}

		// Filter out ARM OABI. http://wiki.embeddedarm.com/wiki/EABI_vs_OABI
		if fields[1] == "oabi" {
			return nil, nil
		}

		num, err := strconv.Atoi(fields[0])
		if err != nil {
			return nil, fmt.Errorf("failed to parse syscall number: %v at '%v'", err, line)
		}

		return &Syscall{
			Num:  num,
			Name: fields[2],
		}, nil
	})
	if err != nil {
		return nil, err
	}

	armUnistdSycallRegex := regexp.MustCompile(
		`^#define __ARM_NR_(?P<syscall>[a-z0-9_]+)\s+\(__ARM_NR_BASE\+(?P<number>\d+)\)`)

	syscallsB, err := readSyscalls(headerPath, dir, func(line string) (*Syscall, error) {
		matches := armUnistdSycallRegex.FindStringSubmatch(line)
		if len(matches) != 3 {
			return nil, nil
		}

		num, err := strconv.Atoi(matches[2])
		if err != nil {
			return nil, fmt.Errorf("failed to parse syscall number: %v at '%v'", err, line)
		}
		num += armNrBase

		return &Syscall{
			Num:  num,
			Name: matches[1],
		}, nil
	})
	if err != nil {
		return nil, err
	}

	syscalls := append(syscallsA, syscallsB...)

	sort.Slice(syscalls, func(i, j int) bool {
		return syscalls[i].Num < syscalls[j].Num
	})

	return &Arch{
		Name:     "ARM",
		Syscalls: syscalls,
	}, nil
}