1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package sym
6
7import (
8	"cmd/internal/objabi"
9	"cmd/internal/sys"
10	"debug/elf"
11	"debug/macho"
12)
13
14// RelocVariant is a linker-internal variation on a relocation.
15type RelocVariant uint8
16
17const (
18	RV_NONE RelocVariant = iota
19	RV_POWER_LO
20	RV_POWER_HI
21	RV_POWER_HA
22	RV_POWER_DS
23
24	// RV_390_DBL is a s390x-specific relocation variant that indicates that
25	// the value to be placed into the relocatable field should first be
26	// divided by 2.
27	RV_390_DBL
28
29	RV_CHECK_OVERFLOW RelocVariant = 1 << 7
30	RV_TYPE_MASK      RelocVariant = RV_CHECK_OVERFLOW - 1
31)
32
33func RelocName(arch *sys.Arch, r objabi.RelocType) string {
34	switch {
35	case r >= objabi.MachoRelocOffset: // Mach-O
36		nr := (r - objabi.MachoRelocOffset) >> 1
37		switch arch.Family {
38		case sys.AMD64:
39			return macho.RelocTypeX86_64(nr).String()
40		case sys.ARM64:
41			return macho.RelocTypeARM64(nr).String()
42		default:
43			panic("unreachable")
44		}
45	case r >= objabi.ElfRelocOffset: // ELF
46		nr := r - objabi.ElfRelocOffset
47		switch arch.Family {
48		case sys.AMD64:
49			return elf.R_X86_64(nr).String()
50		case sys.ARM:
51			return elf.R_ARM(nr).String()
52		case sys.ARM64:
53			return elf.R_AARCH64(nr).String()
54		case sys.I386:
55			return elf.R_386(nr).String()
56		case sys.Loong64:
57			return elf.R_LARCH(nr).String()
58		case sys.MIPS, sys.MIPS64:
59			return elf.R_MIPS(nr).String()
60		case sys.PPC64:
61			return elf.R_PPC64(nr).String()
62		case sys.S390X:
63			return elf.R_390(nr).String()
64		case sys.RISCV64:
65			return elf.R_RISCV(nr).String()
66		default:
67			panic("unreachable")
68		}
69	}
70
71	return r.String()
72}
73