podman

Форк
0
200 строк · 6.4 Кб
1
// Derived from Inferno utils/6l/obj.c and utils/6l/span.c
2
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/obj.c
3
// https://bitbucket.org/inferno-os/inferno-os/src/master/utils/6l/span.c
4
//
5
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
6
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
7
//	Portions Copyright © 1997-1999 Vita Nuova Limited
8
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
9
//	Portions Copyright © 2004,2006 Bruce Ellis
10
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
11
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
12
//	Portions Copyright © 2009 The Go Authors. All rights reserved.
13
//
14
// Permission is hereby granted, free of charge, to any person obtaining a copy
15
// of this software and associated documentation files (the "Software"), to deal
16
// in the Software without restriction, including without limitation the rights
17
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
// copies of the Software, and to permit persons to whom the Software is
19
// furnished to do so, subject to the following conditions:
20
//
21
// The above copyright notice and this permission notice shall be included in
22
// all copies or substantial portions of the Software.
23
//
24
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
27
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30
// THE SOFTWARE.
31

32
package obj
33

34
import (
35
	"github.com/twitchyliquid64/golang-asm/objabi"
36
	"log"
37
	"math"
38
)
39

40
// Grow increases the length of s.P to lsiz.
41
func (s *LSym) Grow(lsiz int64) {
42
	siz := int(lsiz)
43
	if int64(siz) != lsiz {
44
		log.Fatalf("LSym.Grow size %d too long", lsiz)
45
	}
46
	if len(s.P) >= siz {
47
		return
48
	}
49
	s.P = append(s.P, make([]byte, siz-len(s.P))...)
50
}
51

52
// GrowCap increases the capacity of s.P to c.
53
func (s *LSym) GrowCap(c int64) {
54
	if int64(cap(s.P)) >= c {
55
		return
56
	}
57
	if s.P == nil {
58
		s.P = make([]byte, 0, c)
59
		return
60
	}
61
	b := make([]byte, len(s.P), c)
62
	copy(b, s.P)
63
	s.P = b
64
}
65

66
// prepwrite prepares to write data of size siz into s at offset off.
67
func (s *LSym) prepwrite(ctxt *Link, off int64, siz int) {
68
	if off < 0 || siz < 0 || off >= 1<<30 {
69
		ctxt.Diag("prepwrite: bad off=%d siz=%d s=%v", off, siz, s)
70
	}
71
	switch s.Type {
72
	case objabi.Sxxx, objabi.SBSS:
73
		s.Type = objabi.SDATA
74
	case objabi.SNOPTRBSS:
75
		s.Type = objabi.SNOPTRDATA
76
	case objabi.STLSBSS:
77
		ctxt.Diag("cannot supply data for %v var %v", s.Type, s.Name)
78
	}
79
	l := off + int64(siz)
80
	s.Grow(l)
81
	if l > s.Size {
82
		s.Size = l
83
	}
84
}
85

86
// WriteFloat32 writes f into s at offset off.
87
func (s *LSym) WriteFloat32(ctxt *Link, off int64, f float32) {
88
	s.prepwrite(ctxt, off, 4)
89
	ctxt.Arch.ByteOrder.PutUint32(s.P[off:], math.Float32bits(f))
90
}
91

92
// WriteFloat64 writes f into s at offset off.
93
func (s *LSym) WriteFloat64(ctxt *Link, off int64, f float64) {
94
	s.prepwrite(ctxt, off, 8)
95
	ctxt.Arch.ByteOrder.PutUint64(s.P[off:], math.Float64bits(f))
96
}
97

98
// WriteInt writes an integer i of size siz into s at offset off.
99
func (s *LSym) WriteInt(ctxt *Link, off int64, siz int, i int64) {
100
	s.prepwrite(ctxt, off, siz)
101
	switch siz {
102
	default:
103
		ctxt.Diag("WriteInt: bad integer size: %d", siz)
104
	case 1:
105
		s.P[off] = byte(i)
106
	case 2:
107
		ctxt.Arch.ByteOrder.PutUint16(s.P[off:], uint16(i))
108
	case 4:
109
		ctxt.Arch.ByteOrder.PutUint32(s.P[off:], uint32(i))
110
	case 8:
111
		ctxt.Arch.ByteOrder.PutUint64(s.P[off:], uint64(i))
112
	}
113
}
114

115
func (s *LSym) writeAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64, rtype objabi.RelocType) {
116
	// Allow 4-byte addresses for DWARF.
117
	if siz != ctxt.Arch.PtrSize && siz != 4 {
118
		ctxt.Diag("WriteAddr: bad address size %d in %s", siz, s.Name)
119
	}
120
	s.prepwrite(ctxt, off, siz)
121
	r := Addrel(s)
122
	r.Off = int32(off)
123
	if int64(r.Off) != off {
124
		ctxt.Diag("WriteAddr: off overflow %d in %s", off, s.Name)
125
	}
126
	r.Siz = uint8(siz)
127
	r.Sym = rsym
128
	r.Type = rtype
129
	r.Add = roff
130
}
131

132
// WriteAddr writes an address of size siz into s at offset off.
133
// rsym and roff specify the relocation for the address.
134
func (s *LSym) WriteAddr(ctxt *Link, off int64, siz int, rsym *LSym, roff int64) {
135
	s.writeAddr(ctxt, off, siz, rsym, roff, objabi.R_ADDR)
136
}
137

138
// WriteCURelativeAddr writes a pointer-sized address into s at offset off.
139
// rsym and roff specify the relocation for the address which will be
140
// resolved by the linker to an offset from the DW_AT_low_pc attribute of
141
// the DWARF Compile Unit of rsym.
142
func (s *LSym) WriteCURelativeAddr(ctxt *Link, off int64, rsym *LSym, roff int64) {
143
	s.writeAddr(ctxt, off, ctxt.Arch.PtrSize, rsym, roff, objabi.R_ADDRCUOFF)
144
}
145

146
// WriteOff writes a 4 byte offset to rsym+roff into s at offset off.
147
// After linking the 4 bytes stored at s+off will be
148
// rsym+roff-(start of section that s is in).
149
func (s *LSym) WriteOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
150
	s.prepwrite(ctxt, off, 4)
151
	r := Addrel(s)
152
	r.Off = int32(off)
153
	if int64(r.Off) != off {
154
		ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
155
	}
156
	r.Siz = 4
157
	r.Sym = rsym
158
	r.Type = objabi.R_ADDROFF
159
	r.Add = roff
160
}
161

162
// WriteWeakOff writes a weak 4 byte offset to rsym+roff into s at offset off.
163
// After linking the 4 bytes stored at s+off will be
164
// rsym+roff-(start of section that s is in).
165
func (s *LSym) WriteWeakOff(ctxt *Link, off int64, rsym *LSym, roff int64) {
166
	s.prepwrite(ctxt, off, 4)
167
	r := Addrel(s)
168
	r.Off = int32(off)
169
	if int64(r.Off) != off {
170
		ctxt.Diag("WriteOff: off overflow %d in %s", off, s.Name)
171
	}
172
	r.Siz = 4
173
	r.Sym = rsym
174
	r.Type = objabi.R_WEAKADDROFF
175
	r.Add = roff
176
}
177

178
// WriteString writes a string of size siz into s at offset off.
179
func (s *LSym) WriteString(ctxt *Link, off int64, siz int, str string) {
180
	if siz < len(str) {
181
		ctxt.Diag("WriteString: bad string size: %d < %d", siz, len(str))
182
	}
183
	s.prepwrite(ctxt, off, siz)
184
	copy(s.P[off:off+int64(siz)], str)
185
}
186

187
// WriteBytes writes a slice of bytes into s at offset off.
188
func (s *LSym) WriteBytes(ctxt *Link, off int64, b []byte) int64 {
189
	s.prepwrite(ctxt, off, len(b))
190
	copy(s.P[off:], b)
191
	return off + int64(len(b))
192
}
193

194
func Addrel(s *LSym) *Reloc {
195
	if s.R == nil {
196
		s.R = make([]Reloc, 0, 4)
197
	}
198
	s.R = append(s.R, Reloc{})
199
	return &s.R[len(s.R)-1]
200
}
201

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

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

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

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