Add support to the loader for getting/setting the 'variant' property
of a symbol relocation. The variant property handles unusual or
infrequently used relocations that have both a type and a variant of
that type (this is needed for S390).
In the sym.Symbol world, a relocation variant is a field on the
'relocExt' extension that is part of sym.Reloc. In this new
implementation for the loader, reloc variants are stored in a side
table (a map) in the loader, and accessed via loader methods.
Change-Id: I62bf54ae7ff6d500c0ea8d2dbe759b2431087378
Reviewed-on: https://go-review.googlesource.com/c/go/+/227018
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Store external relocations in (almost) the same format as the Go
objects, so we can handle them more uniformly.
There is a small speedup:
(linking cmd/compile)
Deadcode 67.8ms ± 3% 61.1ms ± 3% -9.94% (p=0.008 n=5+5)
Dostkcheck 41.2ms ± 2% 38.8ms ± 3% -5.99% (p=0.008 n=5+5)
Change-Id: I8616e10b26235904201d6c9465f5ae32a49c9949
Reviewed-on: https://go-review.googlesource.com/c/go/+/226365
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This converts the second portion of DWARF-gen (dwarfGenerateDebugSyms
function and friends) to use the loader, as opposed to sym.Symbols.
Second phase is invoked as part of dodata(), which is fairly far along
in the linker, meaning that the "converted to loader.Symbol" wavefront
has not yet reached that point.
To account for this, the patch contains some shim code that runs
initially to copy back things from sym.Symbols into the loader
(notable symbol values), and then a second hook to be code after
dwarf-gen is complete to that copies the results back into the
appropriate sym.Symbols. This code is obviously temporary, but needed
for the time being.
Change-Id: I9b830b08b16480a1a5230cb52b592db1c550af18
Reviewed-on: https://go-review.googlesource.com/c/go/+/220987
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
With unique global indices, MakeSymbolUpdater will not change the
symbol's index. So no need to return a new index.
Change-Id: I5b4fd6a0167cc74476880bbf4382c524ecde7721
Reviewed-on: https://go-review.googlesource.com/c/go/+/219227
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
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>
Currently, the symbol updater uses a pointer pointing to the
loader's payloads array. If the payloads slice grows (and moves),
the pointer may become stale and no longer point to the symbol's
actual payload. Specifically, consider
sb, sym := l.MakeSymbolUpdater(...)
// add a bunch of external symbols, which grows payload slice
sb.SetType(t)
l.SymType(sym) // may not return t
sb.SetType on line 3 may not have the desired effect, as
sb.extSymPayload may no longer point to the right payload. As a
result, the type we get on line 4 may be not the one we set.
Fix this by making the payload's address permanent. Once it is
allocated it will never move.
Change-Id: Iab190ea5aceb5c37f91d09ad4ffd458e881b03f4
Reviewed-on: https://go-review.googlesource.com/c/go/+/217063
Run-TryBot: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
Revamp the way that symbol overwrites are handled to deal with symbols
that are overwritten more than once (such as "_cgo_mmap"). The
scenario here is that a symbol can be overwritten twice, once during
preload, and then again when host objects are read during internal
linking. This can result in a situation where we have two entries in
the overwrite map, from X -> Y and then from Y -> Z. Rather than
search the overwrite map when adding new entries, add a helper routine
for querying the map that catches this situation and fixes it up.
Also with this patch is a couple of tweaks to the loader.Dump method
to insure that it can dump the entire global index space without
crashing due to odd overwrites (as in the scenario above).
Change-Id: Ib6c8a0e03e92fc2b57318001711b501eeaf12249
Reviewed-on: https://go-review.googlesource.com/c/go/+/212098
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
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>
Add SymbolBuilder helper type -- this type provides a set of methods
intended to make it easy to manipulate the content of a symbol (type,
relocations, data, etc).
Change-Id: I579bf8d04650e66d33a9780a6c2347a576c94c6f
Reviewed-on: https://go-review.googlesource.com/c/go/+/210178
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Jeremy Faller <jeremy@golang.org>