...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package time
17
18 import (
19 "bytes"
20 "debug/elf"
21 "embed"
22 "encoding/binary"
23
24 "github.com/go-logr/logr"
25 "github.com/pkg/errors"
26 )
27
28
29 var fakeclock embed.FS
30
31 const textSection = ".text"
32 const relocationSection = ".rela.text"
33
34
35 func LoadFakeImageFromEmbedFs(filename string, symbolName string, logger logr.Logger) (*FakeImage, error) {
36 path := "fakeclock/" + filename
37 object, err := fakeclock.ReadFile(path)
38 if err != nil {
39 return nil, errors.Wrapf(err, "read file from embedded fs %s", path)
40 }
41
42 elfFile, err := elf.NewFile(bytes.NewReader(object))
43 if err != nil {
44 return nil, errors.Wrapf(err, "parse elf file %s", path)
45 }
46
47 syms, err := elfFile.Symbols()
48 if err != nil {
49 return nil, errors.Wrapf(err, "get symbols %s", path)
50 }
51
52 var imageContent []byte
53 imageOffset := make(map[string]int)
54
55 for _, r := range elfFile.Sections {
56
57 if r.Type == elf.SHT_PROGBITS && r.Name == textSection {
58 imageContent, err = r.Data()
59 if err != nil {
60 return nil, errors.Wrapf(err, "read text section data %s", path)
61 }
62 break
63 }
64 }
65
66 for _, r := range elfFile.Sections {
67 if r.Type == elf.SHT_RELA && r.Name == relocationSection {
68 rela_section, err := r.Data()
69 if err != nil {
70 return nil, errors.Wrapf(err, "read rela section data %s", path)
71 }
72 rela_section_reader := bytes.NewReader(rela_section)
73
74 var rela elf.Rela64
75 for rela_section_reader.Len() > 0 {
76 err := binary.Read(rela_section_reader, elfFile.ByteOrder, &rela)
77 if err != nil {
78 return nil, errors.Wrapf(err, "read rela section rela64 entry %s", path)
79 }
80
81 symNo := rela.Info >> 32
82 if symNo == 0 || symNo > uint64(len(syms)) {
83 continue
84 }
85
86 sym := syms[symNo-1]
87 byteorder := elfFile.ByteOrder
88 if elfFile.Machine == elf.EM_X86_64 || elfFile.Machine == elf.EM_AARCH64 {
89 AssetLD(rela, imageOffset, &imageContent, sym, byteorder)
90 } else {
91 return nil, errors.Errorf("unsupported architecture")
92 }
93 }
94
95 break
96 }
97 }
98 return NewFakeImage(
99 symbolName,
100 imageContent,
101 imageOffset,
102 logger,
103 ), nil
104 }
105