Skip to content
Snippets Groups Projects
Commit 24f9b9c8 authored by Than McIntosh's avatar Than McIntosh
Browse files

[dev.link] cmd/link: record external symbol alignment

Add a mechanism for recording symbol alignment for external symbols
under the new loader scheme. Alignments is stored in a side table,
since most symbols don't wind up needing an alignment other than zero.

Change-Id: I97092481412c15eac9b9f4c29b5c273f53759562
Reviewed-on: https://go-review.googlesource.com/c/go/+/210177


Reviewed-by: default avatarCherry Zhang <cherryyz@google.com>
Reviewed-by: default avatarJeremy Faller <jeremy@golang.org>
parent 3c3ba97b
No related branches found
No related tags found
No related merge requests found
...@@ -15,6 +15,7 @@ import ( ...@@ -15,6 +15,7 @@ import (
"cmd/link/internal/sym" "cmd/link/internal/sym"
"fmt" "fmt"
"log" "log"
"math/bits"
"os" "os"
"sort" "sort"
"strconv" "strconv"
...@@ -193,6 +194,8 @@ type Loader struct { ...@@ -193,6 +194,8 @@ type Loader struct {
outer map[Sym]Sym outer map[Sym]Sym
sub map[Sym]Sym sub map[Sym]Sym
align map[Sym]int32 // stores alignment for symbols
// Used to implement field tracking; created during deadcode if // Used to implement field tracking; created during deadcode if
// field tracking is enabled. Reachparent[K] contains the index of // field tracking is enabled. Reachparent[K] contains the index of
// the symbol that triggered the marking of symbol K as live. // the symbol that triggered the marking of symbol K as live.
...@@ -230,6 +233,7 @@ func NewLoader(flags uint32) *Loader { ...@@ -230,6 +233,7 @@ func NewLoader(flags uint32) *Loader {
objByPkg: make(map[string]*oReader), objByPkg: make(map[string]*oReader),
outer: make(map[Sym]Sym), outer: make(map[Sym]Sym),
sub: make(map[Sym]Sym), sub: make(map[Sym]Sym),
align: make(map[Sym]int32),
overwrite: make(map[Sym]Sym), overwrite: make(map[Sym]Sym),
itablink: make(map[Sym]struct{}), itablink: make(map[Sym]struct{}),
extStaticSyms: make(map[nameVer]Sym), extStaticSyms: make(map[nameVer]Sym),
...@@ -906,6 +910,40 @@ func (l *Loader) Data(i Sym) []byte { ...@@ -906,6 +910,40 @@ func (l *Loader) Data(i Sym) []byte {
return r.Data(li) return r.Data(li)
} }
// SymAlign returns the alignment for a symbol.
func (l *Loader) SymAlign(i Sym) int32 {
// If an alignment has been recorded, return that.
if align, ok := l.align[i]; ok {
return align
}
// TODO: would it make sense to return an arch-specific
// alignment depending on section type? E.g. STEXT => 32,
// SDATA => 1, etc?
return 0
}
// SetSymAlign sets the alignment for a symbol.
func (l *Loader) SetSymAlign(i Sym, align int32) {
// reject bad synbols
if i > l.max || i == 0 {
panic("bad symbol index in SetSymAlign")
}
// Reject nonsense alignments.
// TODO: do we need this?
if align < 0 {
panic("bad alignment value")
}
if align == 0 {
delete(l.align, i)
} else {
// Alignment should be a power of 2.
if bits.OnesCount32(uint32(align)) != 1 {
panic("bad alignment value")
}
l.align[i] = align
}
}
// Returns the number of aux symbols given a global index. // Returns the number of aux symbols given a global index.
func (l *Loader) NAux(i Sym) int { func (l *Loader) NAux(i Sym) int {
if l.IsExternal(i) { if l.IsExternal(i) {
......
...@@ -109,6 +109,17 @@ func TestAddMaterializedSymbol(t *testing.T) { ...@@ -109,6 +109,17 @@ func TestAddMaterializedSymbol(t *testing.T) {
t.Errorf("ldr.SetValue(%d,%d): expected %d got %d\n", s, nv, nv, v) t.Errorf("ldr.SetValue(%d,%d): expected %d got %d\n", s, nv, nv, v)
} }
} }
// Check/set alignment
es3al := ldr.SymAlign(es3)
if es3al != 0 {
t.Errorf("SymAlign(es3): expected 0, got %d", es3al)
}
ldr.SetSymAlign(es3, 128)
es3al = ldr.SymAlign(es3)
if es3al != 128 {
t.Errorf("SymAlign(es3): expected 128, got %d", es3al)
}
} }
func TestOuterSub(t *testing.T) { func TestOuterSub(t *testing.T) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment