2019-12-11 14:36:17 -05:00
|
|
|
// Copyright 2019 The Go Authors. All rights reserved.
|
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
|
|
package loader
|
|
|
|
|
|
|
|
|
|
import (
|
2020-03-28 16:46:47 -04:00
|
|
|
"cmd/internal/goobj2"
|
2019-12-11 14:36:17 -05:00
|
|
|
"cmd/internal/objabi"
|
|
|
|
|
"cmd/internal/sys"
|
|
|
|
|
"cmd/link/internal/sym"
|
2020-04-08 19:45:12 -04:00
|
|
|
"sort"
|
2019-12-11 14:36:17 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// SymbolBuilder is a helper designed to help with the construction
|
|
|
|
|
// of new symbol contents.
|
|
|
|
|
type SymbolBuilder struct {
|
|
|
|
|
*extSymPayload // points to payload being updated
|
|
|
|
|
symIdx Sym // index of symbol being updated/constructed
|
|
|
|
|
l *Loader // loader
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 14:14:29 -05:00
|
|
|
// MakeSymbolBuilder creates a symbol builder for use in constructing
|
2019-12-11 14:36:17 -05:00
|
|
|
// an entirely new symbol.
|
|
|
|
|
func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
|
|
|
|
// for now assume that any new sym is intended to be static
|
2020-03-24 12:08:36 -04:00
|
|
|
symIdx := l.CreateStaticSym(name)
|
2019-12-11 14:36:17 -05:00
|
|
|
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
[dev.link] cmd/link: make symbol's global index unique
Currently, when mapping symbol's local index to global index, for
duplicated and overwriting/overwritten symbols, each appearance
of the symbol gets a global index, with one being the "primary",
and others "redirect" to it through the overwrite map. Basically,
the local-global index mapping is one to one, with overwrite/
dedup happening in global index level.
This has a few drawbacks:
- All symbol accesses effectively need to query the overwrite
map. This may hurt performance.
- For multi-level overwrites, (Y overwrites X, Z overwrites Y),
this can get quite complicated, and we have to follow the
redirection recursively.
- Failed to follow or to update the overwrite map leads to bugs.
In this CL, we change the index mapping mechanism so that each
symbol get a unique global index. Multiple appearances of the
same symbol get the same index. Now the local-global index
mapping is N to one. Overwrite/dedup happens directly in the
local-global mapping.
We keep both mapping directions in arrays. Each object carries
an array for its local-global mapping. The loader carries an
array mapping global index to the "primary" local index, which is
the one we should load from. This way, we can get rid of the
overwrite map, and index conversions are simply array accesses.
TODO: we still make reservation of the index space upfront, and
leave holes for dup symbols. Maybe get rid of the reservation and
holes.
Change-Id: Ia251489d5f2ff16a0b3156a71d141a70cdf03a4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/217064
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-01-28 18:18:58 -05:00
|
|
|
sb.extSymPayload = l.getPayload(symIdx)
|
2019-12-11 14:36:17 -05:00
|
|
|
return sb
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-16 14:14:29 -05:00
|
|
|
// MakeSymbolUpdater creates a symbol builder helper for an existing
|
|
|
|
|
// symbol 'symIdx'. If 'symIdx' is not an external symbol, then create
|
|
|
|
|
// a clone of it (copy name, properties, etc) fix things up so that
|
|
|
|
|
// the lookup tables and caches point to the new version, not the old
|
2020-02-12 17:23:47 -05:00
|
|
|
// version.
|
|
|
|
|
func (l *Loader) MakeSymbolUpdater(symIdx Sym) *SymbolBuilder {
|
2019-12-16 14:14:29 -05:00
|
|
|
if symIdx == 0 {
|
|
|
|
|
panic("can't update the null symbol")
|
|
|
|
|
}
|
2019-12-11 14:36:17 -05:00
|
|
|
if !l.IsExternal(symIdx) {
|
2019-12-16 14:14:29 -05:00
|
|
|
// Create a clone with the same name/version/kind etc.
|
[dev.link] cmd/link: make symbol's global index unique
Currently, when mapping symbol's local index to global index, for
duplicated and overwriting/overwritten symbols, each appearance
of the symbol gets a global index, with one being the "primary",
and others "redirect" to it through the overwrite map. Basically,
the local-global index mapping is one to one, with overwrite/
dedup happening in global index level.
This has a few drawbacks:
- All symbol accesses effectively need to query the overwrite
map. This may hurt performance.
- For multi-level overwrites, (Y overwrites X, Z overwrites Y),
this can get quite complicated, and we have to follow the
redirection recursively.
- Failed to follow or to update the overwrite map leads to bugs.
In this CL, we change the index mapping mechanism so that each
symbol get a unique global index. Multiple appearances of the
same symbol get the same index. Now the local-global index
mapping is N to one. Overwrite/dedup happens directly in the
local-global mapping.
We keep both mapping directions in arrays. Each object carries
an array for its local-global mapping. The loader carries an
array mapping global index to the "primary" local index, which is
the one we should load from. This way, we can get rid of the
overwrite map, and index conversions are simply array accesses.
TODO: we still make reservation of the index space upfront, and
leave holes for dup symbols. Maybe get rid of the reservation and
holes.
Change-Id: Ia251489d5f2ff16a0b3156a71d141a70cdf03a4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/217064
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-01-28 18:18:58 -05:00
|
|
|
l.cloneToExternal(symIdx)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
2019-12-16 14:14:29 -05:00
|
|
|
|
|
|
|
|
// Construct updater and return.
|
2019-12-11 14:36:17 -05:00
|
|
|
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
[dev.link] cmd/link: make symbol's global index unique
Currently, when mapping symbol's local index to global index, for
duplicated and overwriting/overwritten symbols, each appearance
of the symbol gets a global index, with one being the "primary",
and others "redirect" to it through the overwrite map. Basically,
the local-global index mapping is one to one, with overwrite/
dedup happening in global index level.
This has a few drawbacks:
- All symbol accesses effectively need to query the overwrite
map. This may hurt performance.
- For multi-level overwrites, (Y overwrites X, Z overwrites Y),
this can get quite complicated, and we have to follow the
redirection recursively.
- Failed to follow or to update the overwrite map leads to bugs.
In this CL, we change the index mapping mechanism so that each
symbol get a unique global index. Multiple appearances of the
same symbol get the same index. Now the local-global index
mapping is N to one. Overwrite/dedup happens directly in the
local-global mapping.
We keep both mapping directions in arrays. Each object carries
an array for its local-global mapping. The loader carries an
array mapping global index to the "primary" local index, which is
the one we should load from. This way, we can get rid of the
overwrite map, and index conversions are simply array accesses.
TODO: we still make reservation of the index space upfront, and
leave holes for dup symbols. Maybe get rid of the reservation and
holes.
Change-Id: Ia251489d5f2ff16a0b3156a71d141a70cdf03a4e
Reviewed-on: https://go-review.googlesource.com/c/go/+/217064
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
2020-01-28 18:18:58 -05:00
|
|
|
sb.extSymPayload = l.getPayload(symIdx)
|
2020-02-12 17:23:47 -05:00
|
|
|
return sb
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
2020-03-11 12:12:41 -04:00
|
|
|
// CreateSymForUpdate creates a symbol with given name and version,
|
|
|
|
|
// returns a CreateSymForUpdate for update. If the symbol already
|
|
|
|
|
// exists, it will update in-place.
|
|
|
|
|
func (l *Loader) CreateSymForUpdate(name string, version int) *SymbolBuilder {
|
2020-06-12 09:35:42 -04:00
|
|
|
s := l.LookupOrCreateSym(name, version)
|
|
|
|
|
l.SetAttrReachable(s, true)
|
|
|
|
|
return l.MakeSymbolUpdater(s)
|
2020-03-11 12:12:41 -04:00
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
// Getters for properties of the symbol we're working on.
|
|
|
|
|
|
2020-01-22 15:24:39 -05:00
|
|
|
func (sb *SymbolBuilder) Sym() Sym { return sb.symIdx }
|
|
|
|
|
func (sb *SymbolBuilder) Name() string { return sb.name }
|
|
|
|
|
func (sb *SymbolBuilder) Version() int { return sb.ver }
|
|
|
|
|
func (sb *SymbolBuilder) Type() sym.SymKind { return sb.kind }
|
|
|
|
|
func (sb *SymbolBuilder) Size() int64 { return sb.size }
|
|
|
|
|
func (sb *SymbolBuilder) Data() []byte { return sb.data }
|
|
|
|
|
func (sb *SymbolBuilder) Value() int64 { return sb.l.SymValue(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) Align() int32 { return sb.l.SymAlign(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) Localentry() uint8 { return sb.l.SymLocalentry(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) OnList() bool { return sb.l.AttrOnList(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) External() bool { return sb.l.AttrExternal(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) Extname() string { return sb.l.SymExtname(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) CgoExportDynamic() bool { return sb.l.AttrCgoExportDynamic(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) Dynimplib() string { return sb.l.SymDynimplib(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) Dynimpvers() string { return sb.l.SymDynimpvers(sb.symIdx) }
|
|
|
|
|
func (sb *SymbolBuilder) SubSym() Sym { return sb.l.SubSym(sb.symIdx) }
|
2020-02-12 17:20:00 -05:00
|
|
|
func (sb *SymbolBuilder) GoType() Sym { return sb.l.SymGoType(sb.symIdx) }
|
2020-03-24 12:08:36 -04:00
|
|
|
func (sb *SymbolBuilder) VisibilityHidden() bool { return sb.l.AttrVisibilityHidden(sb.symIdx) }
|
2020-04-06 15:58:21 -04:00
|
|
|
func (sb *SymbolBuilder) Sect() *sym.Section { return sb.l.SymSect(sb.symIdx) }
|
2019-12-11 14:36:17 -05:00
|
|
|
|
|
|
|
|
// Setters for symbol properties.
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetType(kind sym.SymKind) { sb.kind = kind }
|
|
|
|
|
func (sb *SymbolBuilder) SetSize(size int64) { sb.size = size }
|
|
|
|
|
func (sb *SymbolBuilder) SetData(data []byte) { sb.data = data }
|
2020-01-22 15:24:39 -05:00
|
|
|
func (sb *SymbolBuilder) SetOnList(v bool) { sb.l.SetAttrOnList(sb.symIdx, v) }
|
|
|
|
|
func (sb *SymbolBuilder) SetExternal(v bool) { sb.l.SetAttrExternal(sb.symIdx, v) }
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) SetValue(v int64) { sb.l.SetSymValue(sb.symIdx, v) }
|
|
|
|
|
func (sb *SymbolBuilder) SetAlign(align int32) { sb.l.SetSymAlign(sb.symIdx, align) }
|
|
|
|
|
func (sb *SymbolBuilder) SetLocalentry(value uint8) { sb.l.SetSymLocalentry(sb.symIdx, value) }
|
|
|
|
|
func (sb *SymbolBuilder) SetExtname(value string) { sb.l.SetSymExtname(sb.symIdx, value) }
|
|
|
|
|
func (sb *SymbolBuilder) SetDynimplib(value string) { sb.l.SetSymDynimplib(sb.symIdx, value) }
|
|
|
|
|
func (sb *SymbolBuilder) SetDynimpvers(value string) { sb.l.SetSymDynimpvers(sb.symIdx, value) }
|
2020-01-27 15:31:41 -05:00
|
|
|
func (sb *SymbolBuilder) SetPlt(value int32) { sb.l.SetPlt(sb.symIdx, value) }
|
|
|
|
|
func (sb *SymbolBuilder) SetGot(value int32) { sb.l.SetGot(sb.symIdx, value) }
|
2020-02-12 17:20:00 -05:00
|
|
|
func (sb *SymbolBuilder) SetSpecial(value bool) { sb.l.SetAttrSpecial(sb.symIdx, value) }
|
2020-04-20 18:42:35 -04:00
|
|
|
func (sb *SymbolBuilder) SetLocal(value bool) { sb.l.SetAttrLocal(sb.symIdx, value) }
|
2020-03-24 12:08:36 -04:00
|
|
|
func (sb *SymbolBuilder) SetVisibilityHidden(value bool) {
|
|
|
|
|
sb.l.SetAttrVisibilityHidden(sb.symIdx, value)
|
|
|
|
|
}
|
2020-02-12 17:20:00 -05:00
|
|
|
func (sb *SymbolBuilder) SetNotInSymbolTable(value bool) {
|
|
|
|
|
sb.l.SetAttrNotInSymbolTable(sb.symIdx, value)
|
|
|
|
|
}
|
2020-04-06 15:58:21 -04:00
|
|
|
func (sb *SymbolBuilder) SetSect(sect *sym.Section) { sb.l.SetSymSect(sb.symIdx, sect) }
|
2019-12-11 14:36:17 -05:00
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddBytes(data []byte) {
|
|
|
|
|
if sb.kind == 0 {
|
|
|
|
|
sb.kind = sym.SDATA
|
|
|
|
|
}
|
|
|
|
|
sb.data = append(sb.data, data...)
|
|
|
|
|
sb.size = int64(len(sb.data))
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-28 16:46:47 -04:00
|
|
|
func (sb *SymbolBuilder) Relocs() Relocs {
|
|
|
|
|
return sb.l.Relocs(sb.symIdx)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
2020-07-29 13:20:56 -04:00
|
|
|
// ResetRelocs removes all relocations on this symbol.
|
|
|
|
|
func (sb *SymbolBuilder) ResetRelocs() {
|
|
|
|
|
sb.relocs = sb.relocs[:0]
|
|
|
|
|
sb.reltypes = sb.reltypes[:0]
|
2020-02-14 16:12:51 -05:00
|
|
|
}
|
|
|
|
|
|
2020-04-23 09:18:44 -04:00
|
|
|
// SetRelocType sets the type of the 'i'-th relocation on this sym to 't'
|
|
|
|
|
func (sb *SymbolBuilder) SetRelocType(i int, t objabi.RelocType) {
|
|
|
|
|
sb.relocs[i].SetType(0)
|
|
|
|
|
sb.reltypes[i] = t
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetRelocSym sets the target sym of the 'i'-th relocation on this sym to 's'
|
|
|
|
|
func (sb *SymbolBuilder) SetRelocSym(i int, tgt Sym) {
|
|
|
|
|
sb.relocs[i].SetSym(goobj2.SymRef{PkgIdx: 0, SymIdx: uint32(tgt)})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SetRelocAdd sets the addend of the 'i'-th relocation on this sym to 'a'
|
|
|
|
|
func (sb *SymbolBuilder) SetRelocAdd(i int, a int64) {
|
|
|
|
|
sb.relocs[i].SetAdd(a)
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 19:45:12 -04:00
|
|
|
// Add n relocations, return a handle to the relocations.
|
|
|
|
|
func (sb *SymbolBuilder) AddRelocs(n int) Relocs {
|
2020-04-09 20:45:14 -04:00
|
|
|
sb.relocs = append(sb.relocs, make([]goobj2.Reloc, n)...)
|
2020-04-08 19:45:12 -04:00
|
|
|
sb.reltypes = append(sb.reltypes, make([]objabi.RelocType, n)...)
|
|
|
|
|
return sb.l.Relocs(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Add a relocation with given type, return its handle and index
|
|
|
|
|
// (to set other fields).
|
|
|
|
|
func (sb *SymbolBuilder) AddRel(typ objabi.RelocType) (Reloc2, int) {
|
|
|
|
|
j := len(sb.relocs)
|
2020-04-09 20:45:14 -04:00
|
|
|
sb.relocs = append(sb.relocs, goobj2.Reloc{})
|
2020-04-08 19:45:12 -04:00
|
|
|
sb.reltypes = append(sb.reltypes, typ)
|
|
|
|
|
relocs := sb.Relocs()
|
|
|
|
|
return relocs.At2(j), j
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Sort relocations by offset.
|
|
|
|
|
func (sb *SymbolBuilder) SortRelocs() {
|
|
|
|
|
sort.Sort((*relocsByOff)(sb.extSymPayload))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Implement sort.Interface
|
|
|
|
|
type relocsByOff extSymPayload
|
|
|
|
|
|
|
|
|
|
func (p *relocsByOff) Len() int { return len(p.relocs) }
|
|
|
|
|
func (p *relocsByOff) Less(i, j int) bool { return p.relocs[i].Off() < p.relocs[j].Off() }
|
|
|
|
|
func (p *relocsByOff) Swap(i, j int) {
|
|
|
|
|
p.relocs[i], p.relocs[j] = p.relocs[j], p.relocs[i]
|
|
|
|
|
p.reltypes[i], p.reltypes[j] = p.reltypes[j], p.reltypes[i]
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) Reachable() bool {
|
|
|
|
|
return sb.l.AttrReachable(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-05 21:22:06 -05:00
|
|
|
func (sb *SymbolBuilder) SetReachable(v bool) {
|
|
|
|
|
sb.l.SetAttrReachable(sb.symIdx, v)
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) setReachable() {
|
2020-03-05 21:22:06 -05:00
|
|
|
sb.SetReachable(true)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
2020-01-22 15:24:39 -05:00
|
|
|
func (sb *SymbolBuilder) ReadOnly() bool {
|
|
|
|
|
return sb.l.AttrReadOnly(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetReadOnly(v bool) {
|
|
|
|
|
sb.l.SetAttrReadOnly(sb.symIdx, v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) DuplicateOK() bool {
|
|
|
|
|
return sb.l.AttrDuplicateOK(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetDuplicateOK(v bool) {
|
|
|
|
|
sb.l.SetAttrDuplicateOK(sb.symIdx, v)
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) Outer() Sym {
|
|
|
|
|
return sb.l.OuterSym(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) Sub() Sym {
|
|
|
|
|
return sb.l.SubSym(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SortSub() {
|
|
|
|
|
sb.l.SortSub(sb.symIdx)
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-30 11:30:28 -04:00
|
|
|
func (sb *SymbolBuilder) AddInteriorSym(sub Sym) {
|
|
|
|
|
sb.l.AddInteriorSym(sb.symIdx, sub)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUint8(v uint8) int64 {
|
|
|
|
|
off := sb.size
|
|
|
|
|
if sb.kind == 0 {
|
|
|
|
|
sb.kind = sym.SDATA
|
|
|
|
|
}
|
|
|
|
|
sb.size++
|
|
|
|
|
sb.data = append(sb.data, v)
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUintXX(arch *sys.Arch, v uint64, wid int) int64 {
|
|
|
|
|
off := sb.size
|
|
|
|
|
sb.setUintXX(arch, off, v, int64(wid))
|
|
|
|
|
return off
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) setUintXX(arch *sys.Arch, off int64, v uint64, wid int64) int64 {
|
|
|
|
|
if sb.kind == 0 {
|
|
|
|
|
sb.kind = sym.SDATA
|
|
|
|
|
}
|
|
|
|
|
if sb.size < off+wid {
|
|
|
|
|
sb.size = off + wid
|
|
|
|
|
sb.Grow(sb.size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch wid {
|
|
|
|
|
case 1:
|
|
|
|
|
sb.data[off] = uint8(v)
|
|
|
|
|
case 2:
|
|
|
|
|
arch.ByteOrder.PutUint16(sb.data[off:], uint16(v))
|
|
|
|
|
case 4:
|
|
|
|
|
arch.ByteOrder.PutUint32(sb.data[off:], uint32(v))
|
|
|
|
|
case 8:
|
|
|
|
|
arch.ByteOrder.PutUint64(sb.data[off:], v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return off + wid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUint16(arch *sys.Arch, v uint16) int64 {
|
|
|
|
|
return sb.AddUintXX(arch, uint64(v), 2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUint32(arch *sys.Arch, v uint32) int64 {
|
|
|
|
|
return sb.AddUintXX(arch, uint64(v), 4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUint64(arch *sys.Arch, v uint64) int64 {
|
|
|
|
|
return sb.AddUintXX(arch, v, 8)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddUint(arch *sys.Arch, v uint64) int64 {
|
|
|
|
|
return sb.AddUintXX(arch, v, arch.PtrSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetUint8(arch *sys.Arch, r int64, v uint8) int64 {
|
|
|
|
|
return sb.setUintXX(arch, r, uint64(v), 1)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetUint16(arch *sys.Arch, r int64, v uint16) int64 {
|
|
|
|
|
return sb.setUintXX(arch, r, uint64(v), 2)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetUint32(arch *sys.Arch, r int64, v uint32) int64 {
|
|
|
|
|
return sb.setUintXX(arch, r, uint64(v), 4)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) SetUint(arch *sys.Arch, r int64, v uint64) int64 {
|
|
|
|
|
return sb.setUintXX(arch, r, v, int64(arch.PtrSize))
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 07:35:58 -04:00
|
|
|
func (sb *SymbolBuilder) SetAddrPlus(arch *sys.Arch, off int64, tgt Sym, add int64) int64 {
|
|
|
|
|
if sb.Type() == 0 {
|
|
|
|
|
sb.SetType(sym.SDATA)
|
|
|
|
|
}
|
|
|
|
|
if off+int64(arch.PtrSize) > sb.size {
|
|
|
|
|
sb.size = off + int64(arch.PtrSize)
|
|
|
|
|
sb.Grow(sb.size)
|
|
|
|
|
}
|
2020-07-29 13:20:56 -04:00
|
|
|
r, _ := sb.AddRel(objabi.R_ADDR)
|
|
|
|
|
r.SetSym(tgt)
|
|
|
|
|
r.SetOff(int32(off))
|
|
|
|
|
r.SetSiz(uint8(arch.PtrSize))
|
|
|
|
|
r.SetAdd(add)
|
|
|
|
|
return off + int64(r.Siz())
|
2020-04-08 07:35:58 -04:00
|
|
|
}
|
|
|
|
|
|
2020-04-20 18:42:35 -04:00
|
|
|
func (sb *SymbolBuilder) SetAddr(arch *sys.Arch, off int64, tgt Sym) int64 {
|
|
|
|
|
return sb.SetAddrPlus(arch, off, tgt, 0)
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) Addstring(str string) int64 {
|
|
|
|
|
if sb.kind == 0 {
|
|
|
|
|
sb.kind = sym.SNOPTRDATA
|
|
|
|
|
}
|
|
|
|
|
r := sb.size
|
|
|
|
|
if sb.name == ".shstrtab" {
|
|
|
|
|
// FIXME: find a better mechanism for this
|
2020-05-12 17:16:51 -04:00
|
|
|
sb.l.elfsetstring(str, int(r))
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
sb.data = append(sb.data, str...)
|
|
|
|
|
sb.data = append(sb.data, 0)
|
|
|
|
|
sb.size = int64(len(sb.data))
|
|
|
|
|
return r
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-11 12:12:41 -04:00
|
|
|
func (sb *SymbolBuilder) addSymRef(tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
2019-12-11 14:36:17 -05:00
|
|
|
if sb.kind == 0 {
|
|
|
|
|
sb.kind = sym.SDATA
|
|
|
|
|
}
|
|
|
|
|
i := sb.size
|
|
|
|
|
|
|
|
|
|
sb.size += int64(rsize)
|
|
|
|
|
sb.Grow(sb.size)
|
|
|
|
|
|
2020-07-29 13:20:56 -04:00
|
|
|
r, _ := sb.AddRel(typ)
|
|
|
|
|
r.SetSym(tgt)
|
|
|
|
|
r.SetOff(int32(i))
|
|
|
|
|
r.SetSiz(uint8(rsize))
|
|
|
|
|
r.SetAdd(add)
|
2019-12-11 14:36:17 -05:00
|
|
|
|
2020-07-29 13:20:56 -04:00
|
|
|
return i + int64(rsize)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
2020-03-11 12:12:41 -04:00
|
|
|
// Add a symbol reference (relocation) with given type, addend, and size
|
|
|
|
|
// (the most generic form).
|
|
|
|
|
func (sb *SymbolBuilder) AddSymRef(arch *sys.Arch, tgt Sym, add int64, typ objabi.RelocType, rsize int) int64 {
|
|
|
|
|
return sb.addSymRef(tgt, add, typ, rsize)
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-11 14:36:17 -05:00
|
|
|
func (sb *SymbolBuilder) AddAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
2020-03-11 12:12:41 -04:00
|
|
|
return sb.addSymRef(tgt, add, objabi.R_ADDR, arch.PtrSize)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddAddrPlus4(arch *sys.Arch, tgt Sym, add int64) int64 {
|
2020-03-11 12:12:41 -04:00
|
|
|
return sb.addSymRef(tgt, add, objabi.R_ADDR, 4)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-24 12:08:36 -04:00
|
|
|
func (sb *SymbolBuilder) AddAddr(arch *sys.Arch, tgt Sym) int64 {
|
|
|
|
|
return sb.AddAddrPlus(arch, tgt, 0)
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-11 12:12:41 -04:00
|
|
|
func (sb *SymbolBuilder) AddPCRelPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
|
|
|
|
return sb.addSymRef(tgt, add, objabi.R_PCREL, 4)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddCURelativeAddrPlus(arch *sys.Arch, tgt Sym, add int64) int64 {
|
2020-03-11 12:12:41 -04:00
|
|
|
return sb.addSymRef(tgt, add, objabi.R_ADDRCUOFF, arch.PtrSize)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) AddSize(arch *sys.Arch, tgt Sym) int64 {
|
|
|
|
|
return sb.addSymRef(tgt, 0, objabi.R_SIZE, arch.PtrSize)
|
2019-12-11 14:36:17 -05:00
|
|
|
}
|
2020-04-16 08:29:43 -04:00
|
|
|
|
|
|
|
|
// GenAddAddrPlusFunc returns a function to be called when capturing
|
|
|
|
|
// a function symbol's address. In later stages of the link (when
|
|
|
|
|
// address assignment is done) when doing internal linking and
|
|
|
|
|
// targeting an executable, we can just emit the address of a function
|
|
|
|
|
// directly instead of generating a relocation. Clients can call
|
|
|
|
|
// this function (setting 'internalExec' based on build mode and target)
|
|
|
|
|
// and then invoke the returned function in roughly the same way that
|
|
|
|
|
// loader.*SymbolBuilder.AddAddrPlus would be used.
|
|
|
|
|
func GenAddAddrPlusFunc(internalExec bool) func(s *SymbolBuilder, arch *sys.Arch, tgt Sym, add int64) int64 {
|
|
|
|
|
if internalExec {
|
|
|
|
|
return func(s *SymbolBuilder, arch *sys.Arch, tgt Sym, add int64) int64 {
|
|
|
|
|
if v := s.l.SymValue(tgt); v != 0 {
|
|
|
|
|
return s.AddUint(arch, uint64(v+add))
|
|
|
|
|
}
|
|
|
|
|
return s.AddAddrPlus(arch, tgt, add)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return (*SymbolBuilder).AddAddrPlus
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-04-21 18:37:43 -04:00
|
|
|
|
|
|
|
|
func (sb *SymbolBuilder) MakeWritable() {
|
|
|
|
|
if sb.ReadOnly() {
|
|
|
|
|
sb.data = append([]byte(nil), sb.data...)
|
|
|
|
|
sb.l.SetAttrReadOnly(sb.symIdx, false)
|
|
|
|
|
}
|
|
|
|
|
}
|