podman

Форк
0
871 строка · 23.0 Кб
1
// Copyright 2019 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

5
// This package defines the Go object file format, and provide "low-level" functions
6
// for reading and writing object files.
7

8
// The object file is understood by the compiler, assembler, linker, and tools. They
9
// have "high level" code that operates on object files, handling application-specific
10
// logics, and use this package for the actual reading and writing. Specifically, the
11
// code below:
12
//
13
// - cmd/internal/obj/objfile.go (used by cmd/asm and cmd/compile)
14
// - cmd/internal/objfile/goobj.go (used cmd/nm, cmd/objdump)
15
// - cmd/link/internal/loader package (used by cmd/link)
16
//
17
// If the object file format changes, they may (or may not) need to change.
18

19
package goobj
20

21
import (
22
	"bytes"
23
	"github.com/twitchyliquid64/golang-asm/bio"
24
	"crypto/sha1"
25
	"encoding/binary"
26
	"errors"
27
	"fmt"
28
	"github.com/twitchyliquid64/golang-asm/unsafeheader"
29
	"io"
30
	"unsafe"
31
)
32

33
// New object file format.
34
//
35
//    Header struct {
36
//       Magic       [...]byte   // "\x00go116ld"
37
//       Fingerprint [8]byte
38
//       Flags       uint32
39
//       Offsets     [...]uint32 // byte offset of each block below
40
//    }
41
//
42
//    Strings [...]struct {
43
//       Data [...]byte
44
//    }
45
//
46
//    Autolib  [...]struct { // imported packages (for file loading)
47
//       Pkg         string
48
//       Fingerprint [8]byte
49
//    }
50
//
51
//    PkgIndex [...]string // referenced packages by index
52
//
53
//    Files [...]string
54
//
55
//    SymbolDefs [...]struct {
56
//       Name  string
57
//       ABI   uint16
58
//       Type  uint8
59
//       Flag  uint8
60
//       Flag2 uint8
61
//       Size  uint32
62
//    }
63
//    Hashed64Defs [...]struct { // short hashed (content-addressable) symbol definitions
64
//       ... // same as SymbolDefs
65
//    }
66
//    HashedDefs [...]struct { // hashed (content-addressable) symbol definitions
67
//       ... // same as SymbolDefs
68
//    }
69
//    NonPkgDefs [...]struct { // non-pkg symbol definitions
70
//       ... // same as SymbolDefs
71
//    }
72
//    NonPkgRefs [...]struct { // non-pkg symbol references
73
//       ... // same as SymbolDefs
74
//    }
75
//
76
//    RefFlags [...]struct { // referenced symbol flags
77
//       Sym   symRef
78
//       Flag  uint8
79
//       Flag2 uint8
80
//    }
81
//
82
//    Hash64 [...][8]byte
83
//    Hash   [...][N]byte
84
//
85
//    RelocIndex [...]uint32 // index to Relocs
86
//    AuxIndex   [...]uint32 // index to Aux
87
//    DataIndex  [...]uint32 // offset to Data
88
//
89
//    Relocs [...]struct {
90
//       Off  int32
91
//       Size uint8
92
//       Type uint8
93
//       Add  int64
94
//       Sym  symRef
95
//    }
96
//
97
//    Aux [...]struct {
98
//       Type uint8
99
//       Sym  symRef
100
//    }
101
//
102
//    Data   [...]byte
103
//    Pcdata [...]byte
104
//
105
//    // blocks only used by tools (objdump, nm)
106
//
107
//    RefNames [...]struct { // referenced symbol names
108
//       Sym  symRef
109
//       Name string
110
//       // TODO: include ABI version as well?
111
//    }
112
//
113
// string is encoded as is a uint32 length followed by a uint32 offset
114
// that points to the corresponding string bytes.
115
//
116
// symRef is struct { PkgIdx, SymIdx uint32 }.
117
//
118
// Slice type (e.g. []symRef) is encoded as a length prefix (uint32)
119
// followed by that number of elements.
120
//
121
// The types below correspond to the encoded data structure in the
122
// object file.
123

124
// Symbol indexing.
125
//
126
// Each symbol is referenced with a pair of indices, { PkgIdx, SymIdx },
127
// as the symRef struct above.
128
//
129
// PkgIdx is either a predeclared index (see PkgIdxNone below) or
130
// an index of an imported package. For the latter case, PkgIdx is the
131
// index of the package in the PkgIndex array. 0 is an invalid index.
132
//
133
// SymIdx is the index of the symbol in the given package.
134
// - If PkgIdx is PkgIdxSelf, SymIdx is the index of the symbol in the
135
//   SymbolDefs array.
136
// - If PkgIdx is PkgIdxHashed64, SymIdx is the index of the symbol in the
137
//   Hashed64Defs array.
138
// - If PkgIdx is PkgIdxHashed, SymIdx is the index of the symbol in the
139
//   HashedDefs array.
140
// - If PkgIdx is PkgIdxNone, SymIdx is the index of the symbol in the
141
//   NonPkgDefs array (could natually overflow to NonPkgRefs array).
142
// - Otherwise, SymIdx is the index of the symbol in some other package's
143
//   SymbolDefs array.
144
//
145
// {0, 0} represents a nil symbol. Otherwise PkgIdx should not be 0.
146
//
147
// Hash contains the content hashes of content-addressable symbols, of
148
// which PkgIdx is PkgIdxHashed, in the same order of HashedDefs array.
149
// Hash64 is similar, for PkgIdxHashed64 symbols.
150
//
151
// RelocIndex, AuxIndex, and DataIndex contains indices/offsets to
152
// Relocs/Aux/Data blocks, one element per symbol, first for all the
153
// defined symbols, then all the defined hashed and non-package symbols,
154
// in the same order of SymbolDefs/Hashed64Defs/HashedDefs/NonPkgDefs
155
// arrays. For N total defined symbols, the array is of length N+1. The
156
// last element is the total number of relocations (aux symbols, data
157
// blocks, etc.).
158
//
159
// They can be accessed by index. For the i-th symbol, its relocations
160
// are the RelocIndex[i]-th (inclusive) to RelocIndex[i+1]-th (exclusive)
161
// elements in the Relocs array. Aux/Data are likewise. (The index is
162
// 0-based.)
163

164
// Auxiliary symbols.
165
//
166
// Each symbol may (or may not) be associated with a number of auxiliary
167
// symbols. They are described in the Aux block. See Aux struct below.
168
// Currently a symbol's Gotype, FuncInfo, and associated DWARF symbols
169
// are auxiliary symbols.
170

171
const stringRefSize = 8 // two uint32s
172

173
type FingerprintType [8]byte
174

175
func (fp FingerprintType) IsZero() bool { return fp == FingerprintType{} }
176

177
// Package Index.
178
const (
179
	PkgIdxNone     = (1<<31 - 1) - iota // Non-package symbols
180
	PkgIdxHashed64                      // Short hashed (content-addressable) symbols
181
	PkgIdxHashed                        // Hashed (content-addressable) symbols
182
	PkgIdxBuiltin                       // Predefined runtime symbols (ex: runtime.newobject)
183
	PkgIdxSelf                          // Symbols defined in the current package
184
	PkgIdxInvalid  = 0
185
	// The index of other referenced packages starts from 1.
186
)
187

188
// Blocks
189
const (
190
	BlkAutolib = iota
191
	BlkPkgIdx
192
	BlkFile
193
	BlkSymdef
194
	BlkHashed64def
195
	BlkHasheddef
196
	BlkNonpkgdef
197
	BlkNonpkgref
198
	BlkRefFlags
199
	BlkHash64
200
	BlkHash
201
	BlkRelocIdx
202
	BlkAuxIdx
203
	BlkDataIdx
204
	BlkReloc
205
	BlkAux
206
	BlkData
207
	BlkPcdata
208
	BlkRefName
209
	BlkEnd
210
	NBlk
211
)
212

213
// File header.
214
// TODO: probably no need to export this.
215
type Header struct {
216
	Magic       string
217
	Fingerprint FingerprintType
218
	Flags       uint32
219
	Offsets     [NBlk]uint32
220
}
221

222
const Magic = "\x00go116ld"
223

224
func (h *Header) Write(w *Writer) {
225
	w.RawString(h.Magic)
226
	w.Bytes(h.Fingerprint[:])
227
	w.Uint32(h.Flags)
228
	for _, x := range h.Offsets {
229
		w.Uint32(x)
230
	}
231
}
232

233
func (h *Header) Read(r *Reader) error {
234
	b := r.BytesAt(0, len(Magic))
235
	h.Magic = string(b)
236
	if h.Magic != Magic {
237
		return errors.New("wrong magic, not a Go object file")
238
	}
239
	off := uint32(len(h.Magic))
240
	copy(h.Fingerprint[:], r.BytesAt(off, len(h.Fingerprint)))
241
	off += 8
242
	h.Flags = r.uint32At(off)
243
	off += 4
244
	for i := range h.Offsets {
245
		h.Offsets[i] = r.uint32At(off)
246
		off += 4
247
	}
248
	return nil
249
}
250

251
func (h *Header) Size() int {
252
	return len(h.Magic) + 4 + 4*len(h.Offsets)
253
}
254

255
// Autolib
256
type ImportedPkg struct {
257
	Pkg         string
258
	Fingerprint FingerprintType
259
}
260

261
const importedPkgSize = stringRefSize + 8
262

263
func (p *ImportedPkg) Write(w *Writer) {
264
	w.StringRef(p.Pkg)
265
	w.Bytes(p.Fingerprint[:])
266
}
267

268
// Symbol definition.
269
//
270
// Serialized format:
271
// Sym struct {
272
//    Name  string
273
//    ABI   uint16
274
//    Type  uint8
275
//    Flag  uint8
276
//    Flag2 uint8
277
//    Siz   uint32
278
//    Align uint32
279
// }
280
type Sym [SymSize]byte
281

282
const SymSize = stringRefSize + 2 + 1 + 1 + 1 + 4 + 4
283

284
const SymABIstatic = ^uint16(0)
285

286
const (
287
	ObjFlagShared            = 1 << iota // this object is built with -shared
288
	ObjFlagNeedNameExpansion             // the linker needs to expand `"".` to package path in symbol names
289
	ObjFlagFromAssembly                  // object is from asm src, not go
290
)
291

292
// Sym.Flag
293
const (
294
	SymFlagDupok = 1 << iota
295
	SymFlagLocal
296
	SymFlagTypelink
297
	SymFlagLeaf
298
	SymFlagNoSplit
299
	SymFlagReflectMethod
300
	SymFlagGoType
301
	SymFlagTopFrame
302
)
303

304
// Sym.Flag2
305
const (
306
	SymFlagUsedInIface = 1 << iota
307
	SymFlagItab
308
)
309

310
// Returns the length of the name of the symbol.
311
func (s *Sym) NameLen(r *Reader) int {
312
	return int(binary.LittleEndian.Uint32(s[:]))
313
}
314

315
func (s *Sym) Name(r *Reader) string {
316
	len := binary.LittleEndian.Uint32(s[:])
317
	off := binary.LittleEndian.Uint32(s[4:])
318
	return r.StringAt(off, len)
319
}
320

321
func (s *Sym) ABI() uint16   { return binary.LittleEndian.Uint16(s[8:]) }
322
func (s *Sym) Type() uint8   { return s[10] }
323
func (s *Sym) Flag() uint8   { return s[11] }
324
func (s *Sym) Flag2() uint8  { return s[12] }
325
func (s *Sym) Siz() uint32   { return binary.LittleEndian.Uint32(s[13:]) }
326
func (s *Sym) Align() uint32 { return binary.LittleEndian.Uint32(s[17:]) }
327

328
func (s *Sym) Dupok() bool         { return s.Flag()&SymFlagDupok != 0 }
329
func (s *Sym) Local() bool         { return s.Flag()&SymFlagLocal != 0 }
330
func (s *Sym) Typelink() bool      { return s.Flag()&SymFlagTypelink != 0 }
331
func (s *Sym) Leaf() bool          { return s.Flag()&SymFlagLeaf != 0 }
332
func (s *Sym) NoSplit() bool       { return s.Flag()&SymFlagNoSplit != 0 }
333
func (s *Sym) ReflectMethod() bool { return s.Flag()&SymFlagReflectMethod != 0 }
334
func (s *Sym) IsGoType() bool      { return s.Flag()&SymFlagGoType != 0 }
335
func (s *Sym) TopFrame() bool      { return s.Flag()&SymFlagTopFrame != 0 }
336
func (s *Sym) UsedInIface() bool   { return s.Flag2()&SymFlagUsedInIface != 0 }
337
func (s *Sym) IsItab() bool        { return s.Flag2()&SymFlagItab != 0 }
338

339
func (s *Sym) SetName(x string, w *Writer) {
340
	binary.LittleEndian.PutUint32(s[:], uint32(len(x)))
341
	binary.LittleEndian.PutUint32(s[4:], w.stringOff(x))
342
}
343

344
func (s *Sym) SetABI(x uint16)   { binary.LittleEndian.PutUint16(s[8:], x) }
345
func (s *Sym) SetType(x uint8)   { s[10] = x }
346
func (s *Sym) SetFlag(x uint8)   { s[11] = x }
347
func (s *Sym) SetFlag2(x uint8)  { s[12] = x }
348
func (s *Sym) SetSiz(x uint32)   { binary.LittleEndian.PutUint32(s[13:], x) }
349
func (s *Sym) SetAlign(x uint32) { binary.LittleEndian.PutUint32(s[17:], x) }
350

351
func (s *Sym) Write(w *Writer) { w.Bytes(s[:]) }
352

353
// for testing
354
func (s *Sym) fromBytes(b []byte) { copy(s[:], b) }
355

356
// Symbol reference.
357
type SymRef struct {
358
	PkgIdx uint32
359
	SymIdx uint32
360
}
361

362
// Hash64
363
type Hash64Type [Hash64Size]byte
364

365
const Hash64Size = 8
366

367
// Hash
368
type HashType [HashSize]byte
369

370
const HashSize = sha1.Size
371

372
// Relocation.
373
//
374
// Serialized format:
375
// Reloc struct {
376
//    Off  int32
377
//    Siz  uint8
378
//    Type uint8
379
//    Add  int64
380
//    Sym  SymRef
381
// }
382
type Reloc [RelocSize]byte
383

384
const RelocSize = 4 + 1 + 1 + 8 + 8
385

386
func (r *Reloc) Off() int32  { return int32(binary.LittleEndian.Uint32(r[:])) }
387
func (r *Reloc) Siz() uint8  { return r[4] }
388
func (r *Reloc) Type() uint8 { return r[5] }
389
func (r *Reloc) Add() int64  { return int64(binary.LittleEndian.Uint64(r[6:])) }
390
func (r *Reloc) Sym() SymRef {
391
	return SymRef{binary.LittleEndian.Uint32(r[14:]), binary.LittleEndian.Uint32(r[18:])}
392
}
393

394
func (r *Reloc) SetOff(x int32)  { binary.LittleEndian.PutUint32(r[:], uint32(x)) }
395
func (r *Reloc) SetSiz(x uint8)  { r[4] = x }
396
func (r *Reloc) SetType(x uint8) { r[5] = x }
397
func (r *Reloc) SetAdd(x int64)  { binary.LittleEndian.PutUint64(r[6:], uint64(x)) }
398
func (r *Reloc) SetSym(x SymRef) {
399
	binary.LittleEndian.PutUint32(r[14:], x.PkgIdx)
400
	binary.LittleEndian.PutUint32(r[18:], x.SymIdx)
401
}
402

403
func (r *Reloc) Set(off int32, size uint8, typ uint8, add int64, sym SymRef) {
404
	r.SetOff(off)
405
	r.SetSiz(size)
406
	r.SetType(typ)
407
	r.SetAdd(add)
408
	r.SetSym(sym)
409
}
410

411
func (r *Reloc) Write(w *Writer) { w.Bytes(r[:]) }
412

413
// for testing
414
func (r *Reloc) fromBytes(b []byte) { copy(r[:], b) }
415

416
// Aux symbol info.
417
//
418
// Serialized format:
419
// Aux struct {
420
//    Type uint8
421
//    Sym  SymRef
422
// }
423
type Aux [AuxSize]byte
424

425
const AuxSize = 1 + 8
426

427
// Aux Type
428
const (
429
	AuxGotype = iota
430
	AuxFuncInfo
431
	AuxFuncdata
432
	AuxDwarfInfo
433
	AuxDwarfLoc
434
	AuxDwarfRanges
435
	AuxDwarfLines
436

437
	// TODO: more. Pcdata?
438
)
439

440
func (a *Aux) Type() uint8 { return a[0] }
441
func (a *Aux) Sym() SymRef {
442
	return SymRef{binary.LittleEndian.Uint32(a[1:]), binary.LittleEndian.Uint32(a[5:])}
443
}
444

445
func (a *Aux) SetType(x uint8) { a[0] = x }
446
func (a *Aux) SetSym(x SymRef) {
447
	binary.LittleEndian.PutUint32(a[1:], x.PkgIdx)
448
	binary.LittleEndian.PutUint32(a[5:], x.SymIdx)
449
}
450

451
func (a *Aux) Write(w *Writer) { w.Bytes(a[:]) }
452

453
// for testing
454
func (a *Aux) fromBytes(b []byte) { copy(a[:], b) }
455

456
// Referenced symbol flags.
457
//
458
// Serialized format:
459
// RefFlags struct {
460
//    Sym   symRef
461
//    Flag  uint8
462
//    Flag2 uint8
463
// }
464
type RefFlags [RefFlagsSize]byte
465

466
const RefFlagsSize = 8 + 1 + 1
467

468
func (r *RefFlags) Sym() SymRef {
469
	return SymRef{binary.LittleEndian.Uint32(r[:]), binary.LittleEndian.Uint32(r[4:])}
470
}
471
func (r *RefFlags) Flag() uint8  { return r[8] }
472
func (r *RefFlags) Flag2() uint8 { return r[9] }
473

474
func (r *RefFlags) SetSym(x SymRef) {
475
	binary.LittleEndian.PutUint32(r[:], x.PkgIdx)
476
	binary.LittleEndian.PutUint32(r[4:], x.SymIdx)
477
}
478
func (r *RefFlags) SetFlag(x uint8)  { r[8] = x }
479
func (r *RefFlags) SetFlag2(x uint8) { r[9] = x }
480

481
func (r *RefFlags) Write(w *Writer) { w.Bytes(r[:]) }
482

483
// Referenced symbol name.
484
//
485
// Serialized format:
486
// RefName struct {
487
//    Sym  symRef
488
//    Name string
489
// }
490
type RefName [RefNameSize]byte
491

492
const RefNameSize = 8 + stringRefSize
493

494
func (n *RefName) Sym() SymRef {
495
	return SymRef{binary.LittleEndian.Uint32(n[:]), binary.LittleEndian.Uint32(n[4:])}
496
}
497
func (n *RefName) Name(r *Reader) string {
498
	len := binary.LittleEndian.Uint32(n[8:])
499
	off := binary.LittleEndian.Uint32(n[12:])
500
	return r.StringAt(off, len)
501
}
502

503
func (n *RefName) SetSym(x SymRef) {
504
	binary.LittleEndian.PutUint32(n[:], x.PkgIdx)
505
	binary.LittleEndian.PutUint32(n[4:], x.SymIdx)
506
}
507
func (n *RefName) SetName(x string, w *Writer) {
508
	binary.LittleEndian.PutUint32(n[8:], uint32(len(x)))
509
	binary.LittleEndian.PutUint32(n[12:], w.stringOff(x))
510
}
511

512
func (n *RefName) Write(w *Writer) { w.Bytes(n[:]) }
513

514
type Writer struct {
515
	wr        *bio.Writer
516
	stringMap map[string]uint32
517
	off       uint32 // running offset
518
}
519

520
func NewWriter(wr *bio.Writer) *Writer {
521
	return &Writer{wr: wr, stringMap: make(map[string]uint32)}
522
}
523

524
func (w *Writer) AddString(s string) {
525
	if _, ok := w.stringMap[s]; ok {
526
		return
527
	}
528
	w.stringMap[s] = w.off
529
	w.RawString(s)
530
}
531

532
func (w *Writer) stringOff(s string) uint32 {
533
	off, ok := w.stringMap[s]
534
	if !ok {
535
		panic(fmt.Sprintf("writeStringRef: string not added: %q", s))
536
	}
537
	return off
538
}
539

540
func (w *Writer) StringRef(s string) {
541
	w.Uint32(uint32(len(s)))
542
	w.Uint32(w.stringOff(s))
543
}
544

545
func (w *Writer) RawString(s string) {
546
	w.wr.WriteString(s)
547
	w.off += uint32(len(s))
548
}
549

550
func (w *Writer) Bytes(s []byte) {
551
	w.wr.Write(s)
552
	w.off += uint32(len(s))
553
}
554

555
func (w *Writer) Uint64(x uint64) {
556
	var b [8]byte
557
	binary.LittleEndian.PutUint64(b[:], x)
558
	w.wr.Write(b[:])
559
	w.off += 8
560
}
561

562
func (w *Writer) Uint32(x uint32) {
563
	var b [4]byte
564
	binary.LittleEndian.PutUint32(b[:], x)
565
	w.wr.Write(b[:])
566
	w.off += 4
567
}
568

569
func (w *Writer) Uint16(x uint16) {
570
	var b [2]byte
571
	binary.LittleEndian.PutUint16(b[:], x)
572
	w.wr.Write(b[:])
573
	w.off += 2
574
}
575

576
func (w *Writer) Uint8(x uint8) {
577
	w.wr.WriteByte(x)
578
	w.off++
579
}
580

581
func (w *Writer) Offset() uint32 {
582
	return w.off
583
}
584

585
type Reader struct {
586
	b        []byte // mmapped bytes, if not nil
587
	readonly bool   // whether b is backed with read-only memory
588

589
	rd    io.ReaderAt
590
	start uint32
591
	h     Header // keep block offsets
592
}
593

594
func NewReaderFromBytes(b []byte, readonly bool) *Reader {
595
	r := &Reader{b: b, readonly: readonly, rd: bytes.NewReader(b), start: 0}
596
	err := r.h.Read(r)
597
	if err != nil {
598
		return nil
599
	}
600
	return r
601
}
602

603
func (r *Reader) BytesAt(off uint32, len int) []byte {
604
	if len == 0 {
605
		return nil
606
	}
607
	end := int(off) + len
608
	return r.b[int(off):end:end]
609
}
610

611
func (r *Reader) uint64At(off uint32) uint64 {
612
	b := r.BytesAt(off, 8)
613
	return binary.LittleEndian.Uint64(b)
614
}
615

616
func (r *Reader) int64At(off uint32) int64 {
617
	return int64(r.uint64At(off))
618
}
619

620
func (r *Reader) uint32At(off uint32) uint32 {
621
	b := r.BytesAt(off, 4)
622
	return binary.LittleEndian.Uint32(b)
623
}
624

625
func (r *Reader) int32At(off uint32) int32 {
626
	return int32(r.uint32At(off))
627
}
628

629
func (r *Reader) uint16At(off uint32) uint16 {
630
	b := r.BytesAt(off, 2)
631
	return binary.LittleEndian.Uint16(b)
632
}
633

634
func (r *Reader) uint8At(off uint32) uint8 {
635
	b := r.BytesAt(off, 1)
636
	return b[0]
637
}
638

639
func (r *Reader) StringAt(off uint32, len uint32) string {
640
	b := r.b[off : off+len]
641
	if r.readonly {
642
		return toString(b) // backed by RO memory, ok to make unsafe string
643
	}
644
	return string(b)
645
}
646

647
func toString(b []byte) string {
648
	if len(b) == 0 {
649
		return ""
650
	}
651

652
	var s string
653
	hdr := (*unsafeheader.String)(unsafe.Pointer(&s))
654
	hdr.Data = unsafe.Pointer(&b[0])
655
	hdr.Len = len(b)
656

657
	return s
658
}
659

660
func (r *Reader) StringRef(off uint32) string {
661
	l := r.uint32At(off)
662
	return r.StringAt(r.uint32At(off+4), l)
663
}
664

665
func (r *Reader) Fingerprint() FingerprintType {
666
	return r.h.Fingerprint
667
}
668

669
func (r *Reader) Autolib() []ImportedPkg {
670
	n := (r.h.Offsets[BlkAutolib+1] - r.h.Offsets[BlkAutolib]) / importedPkgSize
671
	s := make([]ImportedPkg, n)
672
	off := r.h.Offsets[BlkAutolib]
673
	for i := range s {
674
		s[i].Pkg = r.StringRef(off)
675
		copy(s[i].Fingerprint[:], r.BytesAt(off+stringRefSize, len(s[i].Fingerprint)))
676
		off += importedPkgSize
677
	}
678
	return s
679
}
680

681
func (r *Reader) Pkglist() []string {
682
	n := (r.h.Offsets[BlkPkgIdx+1] - r.h.Offsets[BlkPkgIdx]) / stringRefSize
683
	s := make([]string, n)
684
	off := r.h.Offsets[BlkPkgIdx]
685
	for i := range s {
686
		s[i] = r.StringRef(off)
687
		off += stringRefSize
688
	}
689
	return s
690
}
691

692
func (r *Reader) NPkg() int {
693
	return int(r.h.Offsets[BlkPkgIdx+1]-r.h.Offsets[BlkPkgIdx]) / stringRefSize
694
}
695

696
func (r *Reader) Pkg(i int) string {
697
	off := r.h.Offsets[BlkPkgIdx] + uint32(i)*stringRefSize
698
	return r.StringRef(off)
699
}
700

701
func (r *Reader) NFile() int {
702
	return int(r.h.Offsets[BlkFile+1]-r.h.Offsets[BlkFile]) / stringRefSize
703
}
704

705
func (r *Reader) File(i int) string {
706
	off := r.h.Offsets[BlkFile] + uint32(i)*stringRefSize
707
	return r.StringRef(off)
708
}
709

710
func (r *Reader) NSym() int {
711
	return int(r.h.Offsets[BlkSymdef+1]-r.h.Offsets[BlkSymdef]) / SymSize
712
}
713

714
func (r *Reader) NHashed64def() int {
715
	return int(r.h.Offsets[BlkHashed64def+1]-r.h.Offsets[BlkHashed64def]) / SymSize
716
}
717

718
func (r *Reader) NHasheddef() int {
719
	return int(r.h.Offsets[BlkHasheddef+1]-r.h.Offsets[BlkHasheddef]) / SymSize
720
}
721

722
func (r *Reader) NNonpkgdef() int {
723
	return int(r.h.Offsets[BlkNonpkgdef+1]-r.h.Offsets[BlkNonpkgdef]) / SymSize
724
}
725

726
func (r *Reader) NNonpkgref() int {
727
	return int(r.h.Offsets[BlkNonpkgref+1]-r.h.Offsets[BlkNonpkgref]) / SymSize
728
}
729

730
// SymOff returns the offset of the i-th symbol.
731
func (r *Reader) SymOff(i uint32) uint32 {
732
	return r.h.Offsets[BlkSymdef] + uint32(i*SymSize)
733
}
734

735
// Sym returns a pointer to the i-th symbol.
736
func (r *Reader) Sym(i uint32) *Sym {
737
	off := r.SymOff(i)
738
	return (*Sym)(unsafe.Pointer(&r.b[off]))
739
}
740

741
// NRefFlags returns the number of referenced symbol flags.
742
func (r *Reader) NRefFlags() int {
743
	return int(r.h.Offsets[BlkRefFlags+1]-r.h.Offsets[BlkRefFlags]) / RefFlagsSize
744
}
745

746
// RefFlags returns a pointer to the i-th referenced symbol flags.
747
// Note: here i is not a local symbol index, just a counter.
748
func (r *Reader) RefFlags(i int) *RefFlags {
749
	off := r.h.Offsets[BlkRefFlags] + uint32(i*RefFlagsSize)
750
	return (*RefFlags)(unsafe.Pointer(&r.b[off]))
751
}
752

753
// Hash64 returns the i-th short hashed symbol's hash.
754
// Note: here i is the index of short hashed symbols, not all symbols
755
// (unlike other accessors).
756
func (r *Reader) Hash64(i uint32) uint64 {
757
	off := r.h.Offsets[BlkHash64] + uint32(i*Hash64Size)
758
	return r.uint64At(off)
759
}
760

761
// Hash returns a pointer to the i-th hashed symbol's hash.
762
// Note: here i is the index of hashed symbols, not all symbols
763
// (unlike other accessors).
764
func (r *Reader) Hash(i uint32) *HashType {
765
	off := r.h.Offsets[BlkHash] + uint32(i*HashSize)
766
	return (*HashType)(unsafe.Pointer(&r.b[off]))
767
}
768

769
// NReloc returns the number of relocations of the i-th symbol.
770
func (r *Reader) NReloc(i uint32) int {
771
	relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4)
772
	return int(r.uint32At(relocIdxOff+4) - r.uint32At(relocIdxOff))
773
}
774

775
// RelocOff returns the offset of the j-th relocation of the i-th symbol.
776
func (r *Reader) RelocOff(i uint32, j int) uint32 {
777
	relocIdxOff := r.h.Offsets[BlkRelocIdx] + uint32(i*4)
778
	relocIdx := r.uint32At(relocIdxOff)
779
	return r.h.Offsets[BlkReloc] + (relocIdx+uint32(j))*uint32(RelocSize)
780
}
781

782
// Reloc returns a pointer to the j-th relocation of the i-th symbol.
783
func (r *Reader) Reloc(i uint32, j int) *Reloc {
784
	off := r.RelocOff(i, j)
785
	return (*Reloc)(unsafe.Pointer(&r.b[off]))
786
}
787

788
// Relocs returns a pointer to the relocations of the i-th symbol.
789
func (r *Reader) Relocs(i uint32) []Reloc {
790
	off := r.RelocOff(i, 0)
791
	n := r.NReloc(i)
792
	return (*[1 << 20]Reloc)(unsafe.Pointer(&r.b[off]))[:n:n]
793
}
794

795
// NAux returns the number of aux symbols of the i-th symbol.
796
func (r *Reader) NAux(i uint32) int {
797
	auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
798
	return int(r.uint32At(auxIdxOff+4) - r.uint32At(auxIdxOff))
799
}
800

801
// AuxOff returns the offset of the j-th aux symbol of the i-th symbol.
802
func (r *Reader) AuxOff(i uint32, j int) uint32 {
803
	auxIdxOff := r.h.Offsets[BlkAuxIdx] + i*4
804
	auxIdx := r.uint32At(auxIdxOff)
805
	return r.h.Offsets[BlkAux] + (auxIdx+uint32(j))*uint32(AuxSize)
806
}
807

808
// Aux returns a pointer to the j-th aux symbol of the i-th symbol.
809
func (r *Reader) Aux(i uint32, j int) *Aux {
810
	off := r.AuxOff(i, j)
811
	return (*Aux)(unsafe.Pointer(&r.b[off]))
812
}
813

814
// Auxs returns the aux symbols of the i-th symbol.
815
func (r *Reader) Auxs(i uint32) []Aux {
816
	off := r.AuxOff(i, 0)
817
	n := r.NAux(i)
818
	return (*[1 << 20]Aux)(unsafe.Pointer(&r.b[off]))[:n:n]
819
}
820

821
// DataOff returns the offset of the i-th symbol's data.
822
func (r *Reader) DataOff(i uint32) uint32 {
823
	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
824
	return r.h.Offsets[BlkData] + r.uint32At(dataIdxOff)
825
}
826

827
// DataSize returns the size of the i-th symbol's data.
828
func (r *Reader) DataSize(i uint32) int {
829
	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
830
	return int(r.uint32At(dataIdxOff+4) - r.uint32At(dataIdxOff))
831
}
832

833
// Data returns the i-th symbol's data.
834
func (r *Reader) Data(i uint32) []byte {
835
	dataIdxOff := r.h.Offsets[BlkDataIdx] + i*4
836
	base := r.h.Offsets[BlkData]
837
	off := r.uint32At(dataIdxOff)
838
	end := r.uint32At(dataIdxOff + 4)
839
	return r.BytesAt(base+off, int(end-off))
840
}
841

842
// AuxDataBase returns the base offset of the aux data block.
843
func (r *Reader) PcdataBase() uint32 {
844
	return r.h.Offsets[BlkPcdata]
845
}
846

847
// NRefName returns the number of referenced symbol names.
848
func (r *Reader) NRefName() int {
849
	return int(r.h.Offsets[BlkRefName+1]-r.h.Offsets[BlkRefName]) / RefNameSize
850
}
851

852
// RefName returns a pointer to the i-th referenced symbol name.
853
// Note: here i is not a local symbol index, just a counter.
854
func (r *Reader) RefName(i int) *RefName {
855
	off := r.h.Offsets[BlkRefName] + uint32(i*RefNameSize)
856
	return (*RefName)(unsafe.Pointer(&r.b[off]))
857
}
858

859
// ReadOnly returns whether r.BytesAt returns read-only bytes.
860
func (r *Reader) ReadOnly() bool {
861
	return r.readonly
862
}
863

864
// Flags returns the flag bits read from the object file header.
865
func (r *Reader) Flags() uint32 {
866
	return r.h.Flags
867
}
868

869
func (r *Reader) Shared() bool            { return r.Flags()&ObjFlagShared != 0 }
870
func (r *Reader) NeedNameExpansion() bool { return r.Flags()&ObjFlagNeedNameExpansion != 0 }
871
func (r *Reader) FromAssembly() bool      { return r.Flags()&ObjFlagFromAssembly != 0 }
872

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

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

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

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