// the section will go, "s" is the symbol to be placed into the new
// section, and "rwx" contains permissions for the section.
func (state *dodataState) allocateDataSectionForSym(seg *sym.Segment, s *sym.Symbol, rwx int) *sym.Section {
- sect := addsection(state.ctxt.Arch, seg, s.Name, rwx)
+ sect := addsection(state.ctxt.loader, state.ctxt.Arch, seg, s.Name, rwx)
sect.Align = symalign(s)
state.datsize = Rnd(state.datsize, int64(sect.Align))
sect.Vaddr = uint64(state.datsize)
// range of symbol types to be put into the section, and "rwx"
// contains permissions for the section.
func (state *dodataState) allocateNamedDataSection(seg *sym.Segment, sName string, types []sym.SymKind, rwx int) *sym.Section {
- sect := addsection(state.ctxt.Arch, seg, sName, rwx)
+ sect := addsection(state.ctxt.loader, state.ctxt.Arch, seg, sName, rwx)
if len(types) == 0 {
sect.Align = 1
} else if len(types) == 1 {
var sect *sym.Section
// FIXME: not clear why it is sometimes necessary to suppress .tbss section creation.
if (ctxt.IsELF || ctxt.HeadType == objabi.Haix) && (ctxt.LinkMode == LinkExternal || !*FlagD) {
- sect = addsection(ctxt.Arch, &Segdata, ".tbss", 06)
+ sect = addsection(ctxt.loader, ctxt.Arch, &Segdata, ".tbss", 06)
sect.Align = int32(ctxt.Arch.PtrSize)
// FIXME: why does this need to be set to zero?
sect.Vaddr = 0
// assign addresses to text
func (ctxt *Link) textaddress() {
- addsection(ctxt.Arch, &Segtext, ".text", 05)
+ addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
// Assign PCs in text segment.
// Could parallelize, by assigning to text
sect.Length = va - sect.Vaddr
// Create new section, set the starting Vaddr
- sect = addsection(ctxt.Arch, &Segtext, ".text", 05)
+ sect = addsection(ctxt.loader, ctxt.Arch, &Segtext, ".text", 05)
sect.Vaddr = va
ldr.SetSymSect(s, sect)
Segdwarf.Sections = append(Segdwarf.Sections, s.Sect)
} else {
compressedSegName := ".zdebug_" + s.Sect.Name[len(".debug_"):]
- sect := addsection(ctxt.Arch, &Segdwarf, compressedSegName, 04)
+ sect := addsection(ctxt.loader, ctxt.Arch, &Segdwarf, compressedSegName, 04)
sect.Length = uint64(len(z.compressed))
newSym := ctxt.Syms.Lookup(compressedSegName, 0)
newSym.P = z.compressed
ctxt.Shlibs = append(ctxt.Shlibs, Shlib{Path: libpath, Hash: hash, Deps: deps, File: f})
}
-func addsection(arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
- sect := new(sym.Section)
+func addsection(ldr *loader.Loader, arch *sys.Arch, seg *sym.Segment, name string, rwx int) *sym.Section {
+ sect := ldr.NewSection()
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
payloadBatch []extSymPayload
payloads []*extSymPayload // contents of linker-materialized external syms
values []int64 // symbol values, indexed by global sym index
- sects []*sym.Section // symbol's section, indexed by global index
+
+ sects []*sym.Section // sections
+ symSects []uint16 // symbol's section, index to sects array
itablink map[Sym]struct{} // itablink[j] defined if j is go.itablink.*
builtinSyms: make([]Sym, nbuiltin),
flags: flags,
elfsetstring: elfsetstring,
+ sects: []*sym.Section{nil}, // reserve index 0 for nil section
}
}
curLen := len(l.values)
if reqLen > curLen {
l.values = append(l.values, make([]int64, reqLen+1-curLen)...)
- l.sects = append(l.sects, make([]*sym.Section, reqLen+1-curLen)...)
}
}
// SymValue returns the section of the i-th symbol. i is global index.
func (l *Loader) SymSect(i Sym) *sym.Section {
- return l.sects[i]
+ return l.sects[l.symSects[i]]
}
// SetSymValue sets the section of the i-th symbol. i is global index.
func (l *Loader) SetSymSect(i Sym, sect *sym.Section) {
- l.sects[i] = sect
+ if int(i) >= len(l.symSects) {
+ l.symSects = append(l.symSects, make([]uint16, l.NSym()-len(l.symSects))...)
+ }
+ l.symSects[i] = sect.Index
+}
+
+// growSects grows the slice used to store symbol sections.
+func (l *Loader) growSects(reqLen int) {
+ curLen := len(l.symSects)
+ if reqLen > curLen {
+ l.symSects = append(l.symSects, make([]uint16, reqLen+1-curLen)...)
+ }
+}
+
+// NewSection creates a new (output) section.
+func (l *Loader) NewSection() *sym.Section {
+ sect := new(sym.Section)
+ idx := len(l.sects)
+ if idx != int(uint16(idx)) {
+ panic("too many sections created")
+ }
+ sect.Index = uint16(idx)
+ l.sects = append(l.sects, sect)
+ return sect
}
// SymDynImplib returns the "dynimplib" attribute for the specified
func (l *Loader) LoadFull(arch *sys.Arch, syms *sym.Symbols) {
// create all Symbols first.
l.growSyms(l.NSym())
+ l.growSects(l.NSym())
nr := 0 // total number of sym.Reloc's we'll need
for _, o := range l.objs[1:] {
Reloff uint64
Rellen uint64
Sym *Symbol // symbol for the section, if any
+ Index uint16 // each section has a unique index, used internally
}