mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.link] cmd/link: support updates to contents of obj-based Syms
Add in the hooks to SymbolBuilder and to the loader to allow the linker to make modifications to a non-external symbol (e.g. a sym whose index is less than loader.extStart). The basic idea is to manufacture a new external symbol with the same name and version, then import the old symbol's content (type, data, relocations, etc) into the payload struct for the new symbol, and finally redirect the name lookup tables to target the new sym for the specified name/version. This change is needed in order to convert over the host object loaders to avoid use of sym.Symbol. Change-Id: I79cd42b23794e830bbdbcbcd2c500c35c351f01f Reviewed-on: https://go-review.googlesource.com/c/go/+/211897 Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
a52cea446d
commit
d5854bf8e6
3 changed files with 261 additions and 85 deletions
|
|
@ -18,7 +18,7 @@ type SymbolBuilder struct {
|
|||
l *Loader // loader
|
||||
}
|
||||
|
||||
// NewSymbolBuilder creates a symbol builder for use in constructing
|
||||
// MakeSymbolBuilder creates a symbol builder for use in constructing
|
||||
// an entirely new symbol.
|
||||
func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
||||
// for now assume that any new sym is intended to be static
|
||||
|
|
@ -31,18 +31,31 @@ func (l *Loader) MakeSymbolBuilder(name string) *SymbolBuilder {
|
|||
return sb
|
||||
}
|
||||
|
||||
// NewSymbolBuilder creates a symbol builder helper for an already-allocated
|
||||
// external symbol 'symIdx'.
|
||||
func (l *Loader) MakeSymbolUpdater(symIdx Sym) *SymbolBuilder {
|
||||
// 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
|
||||
// version. Returns a SymbolBuilder and a Sym (which may be different
|
||||
// from the original if we had to clone).
|
||||
func (l *Loader) MakeSymbolUpdater(symIdx Sym) (*SymbolBuilder, Sym) {
|
||||
if symIdx == 0 {
|
||||
panic("can't update the null symbol")
|
||||
}
|
||||
if ov, ok := l.overwrite[symIdx]; ok {
|
||||
symIdx = ov
|
||||
}
|
||||
if !l.IsExternal(symIdx) {
|
||||
panic("can't build on non-external sym")
|
||||
// Create a clone with the same name/version/kind etc.
|
||||
symIdx = l.cloneToExternal(symIdx)
|
||||
}
|
||||
if l.Syms[symIdx] != nil {
|
||||
panic("can't build if sym.Symbol already present")
|
||||
}
|
||||
|
||||
// Construct updater and return.
|
||||
sb := &SymbolBuilder{l: l, symIdx: symIdx}
|
||||
sb.extSymPayload = &l.payloads[symIdx-l.extStart]
|
||||
return sb
|
||||
return sb, symIdx
|
||||
}
|
||||
|
||||
// Getters for properties of the symbol we're working on.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue