podman

Форк
0
220 строк · 6.1 Кб
1
//go:build !remote
2

3
package emulation
4

5
import (
6
	"debug/elf"
7
	"encoding/binary"
8
	"fmt"
9
	"sync"
10

11
	"github.com/sirupsen/logrus"
12
)
13

14
type elfPlatform struct {
15
	platform string
16
	osabi    []elf.OSABI
17
	class    elf.Class
18
	data     elf.Data
19
	alsoNone bool // also try with data=none,version=0
20
	machine  elf.Machine
21
	flags    []uint32
22
}
23

24
var (
25
	// knownELFPlatformHeaders is a mapping from target platform names and
26
	// plausible headers for the binaries built for those platforms.  Call
27
	// getKnownELFPlatformHeaders() instead of reading this map directly.
28
	knownELFPlatformHeaders     = make(map[string][][]byte)
29
	knownELFPlatformHeadersOnce sync.Once
30
	// knownELFPlatforms is a table of target platforms that we built a
31
	// trivial program for, and the other fields are filled in based on
32
	// what we got when we ran eu-readelf -h against the results.
33
	knownELFPlatforms = []elfPlatform{
34
		{
35
			platform: "linux/386",
36
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
37
			class:    elf.ELFCLASS32,
38
			data:     elf.ELFDATA2LSB,
39
			alsoNone: true,
40
			machine:  elf.EM_386,
41
		},
42
		{
43
			platform: "linux/amd64",
44
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
45
			class:    elf.ELFCLASS64,
46
			data:     elf.ELFDATA2LSB,
47
			alsoNone: true,
48
			machine:  elf.EM_X86_64,
49
		},
50
		{
51
			platform: "linux/arm",
52
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
53
			class:    elf.ELFCLASS32,
54
			data:     elf.ELFDATA2LSB,
55
			machine:  elf.EM_ARM,
56
		},
57
		{
58
			platform: "linux/arm64",
59
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
60
			class:    elf.ELFCLASS64,
61
			data:     elf.ELFDATA2LSB,
62
			machine:  elf.EM_AARCH64,
63
		},
64
		{
65
			platform: "linux/arm64be",
66
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
67
			class:    elf.ELFCLASS64,
68
			data:     elf.ELFDATA2MSB,
69
			machine:  elf.EM_AARCH64,
70
		},
71
		{
72
			platform: "linux/loong64",
73
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
74
			class:    elf.ELFCLASS64,
75
			data:     elf.ELFDATA2LSB,
76
			machine:  elf.EM_LOONGARCH,
77
		},
78
		{
79
			platform: "linux/mips",
80
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
81
			class:    elf.ELFCLASS32,
82
			data:     elf.ELFDATA2MSB,
83
			machine:  elf.EM_MIPS,
84
			flags:    []uint32{0, 2}, // elf.EF_MIPS_PIC set, or not
85
		},
86
		{
87
			platform: "linux/mipsle",
88
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
89
			class:    elf.ELFCLASS32,
90
			data:     elf.ELFDATA2LSB,
91
			machine:  elf.EM_MIPS_RS3_LE,
92
			flags:    []uint32{0, 2}, // elf.EF_MIPS_PIC set, or not
93
		},
94
		{
95
			platform: "linux/mips64",
96
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
97
			class:    elf.ELFCLASS64,
98
			data:     elf.ELFDATA2MSB,
99
			machine:  elf.EM_MIPS,
100
			flags:    []uint32{0, 2}, // elf.EF_MIPS_PIC set, or not
101
		},
102
		{
103
			platform: "linux/mips64le",
104
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
105
			class:    elf.ELFCLASS64,
106
			data:     elf.ELFDATA2LSB,
107
			machine:  elf.EM_MIPS_RS3_LE,
108
			flags:    []uint32{0, 2}, // elf.EF_MIPS_PIC set, or not
109
		},
110
		{
111
			platform: "linux/ppc",
112
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
113
			class:    elf.ELFCLASS32,
114
			data:     elf.ELFDATA2MSB,
115
			machine:  elf.EM_PPC,
116
		},
117
		{
118
			platform: "linux/ppc64",
119
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
120
			class:    elf.ELFCLASS64,
121
			data:     elf.ELFDATA2MSB,
122
			machine:  elf.EM_PPC64,
123
		},
124
		{
125
			platform: "linux/ppc64le",
126
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
127
			class:    elf.ELFCLASS64,
128
			data:     elf.ELFDATA2LSB,
129
			machine:  elf.EM_PPC64,
130
		},
131
		{
132
			platform: "linux/riscv32",
133
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
134
			class:    elf.ELFCLASS32,
135
			data:     elf.ELFDATA2LSB,
136
			machine:  elf.EM_RISCV,
137
		},
138
		{
139
			platform: "linux/riscv64",
140
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
141
			class:    elf.ELFCLASS64,
142
			data:     elf.ELFDATA2LSB,
143
			machine:  elf.EM_RISCV,
144
		},
145
		{
146
			platform: "linux/s390x",
147
			osabi:    []elf.OSABI{elf.ELFOSABI_NONE, elf.ELFOSABI_LINUX},
148
			class:    elf.ELFCLASS64,
149
			data:     elf.ELFDATA2MSB,
150
			machine:  elf.EM_S390,
151
		},
152
	}
153
)
154

155
// header generates an approximation of what the initial N bytes of a binary
156
// built for a given target looks like
157
func (e *elfPlatform) header() ([][]byte, error) {
158
	var headers [][]byte
159
	osabi := e.osabi
160
	if len(osabi) == 0 {
161
		osabi = []elf.OSABI{elf.ELFOSABI_NONE}
162
	}
163
	for i := range osabi {
164
		flags := e.flags
165
		if len(flags) == 0 {
166
			flags = []uint32{0}
167
		}
168
		for f := range flags {
169
			var endian binary.ByteOrder
170
			var entrySize, phoffSize, shoffSize int
171
			header := make([]byte, 40)
172
			copy(header, elf.ELFMAG)
173
			switch e.class {
174
			case elf.ELFCLASS32:
175
				entrySize, phoffSize, shoffSize = 2, 2, 2
176
			case elf.ELFCLASS64:
177
				entrySize, phoffSize, shoffSize = 4, 4, 4
178
			}
179
			switch e.data {
180
			case elf.ELFDATA2LSB:
181
				endian = binary.LittleEndian
182
			case elf.ELFDATA2MSB:
183
				endian = binary.BigEndian
184
			default:
185
				return nil, fmt.Errorf("internal error in entry for %q", e.platform)
186
			}
187
			header[elf.EI_OSABI] = byte(osabi[i])
188
			header[elf.EI_CLASS] = byte(e.class)
189
			header[elf.EI_DATA] = byte(e.data)
190
			header[elf.EI_VERSION] = byte(elf.EV_CURRENT)
191
			header[elf.EI_ABIVERSION] = 0
192
			endian.PutUint16(header[16:], uint16(elf.ET_EXEC))
193
			endian.PutUint16(header[18:], uint16(e.machine))
194
			endian.PutUint32(header[20:], uint32(elf.EV_CURRENT))
195
			endian.PutUint32(header[24+entrySize+phoffSize+shoffSize:], flags[f])
196
			headers = append(headers, append([]byte{}, header...))
197
			if e.alsoNone {
198
				header[elf.EI_DATA] = byte(elf.ELFDATANONE)
199
				header[elf.EI_VERSION] = byte(elf.EV_NONE)
200
				endian.PutUint32(header[20:], uint32(elf.EV_NONE))
201
				headers = append(headers, append([]byte{}, header...))
202
			}
203
		}
204
	}
205
	return headers, nil
206
}
207

208
func getKnownELFPlatformHeaders() map[string][][]byte {
209
	knownELFPlatformHeadersOnce.Do(func() {
210
		for _, p := range knownELFPlatforms {
211
			headerList, err := p.header()
212
			if err != nil {
213
				logrus.Errorf("generating headers for %q: %v\n", p.platform, err)
214
				continue
215
			}
216
			knownELFPlatformHeaders[p.platform] = headerList
217
		}
218
	})
219
	return knownELFPlatformHeaders
220
}
221

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.