return Rnd(datsize, int64(symalign(s)))
}
-// maxalign returns the maximum required alignment for
-// the slice of symbols syms
-func maxalign(syms []*LSym) int32 {
- var max int32
- for _, sym := range syms {
- align := symalign(sym)
- if max < align {
- max = align
- }
- }
- return max
-}
-
const debugGCProg = false
type GCProg struct {
return s1.name < s2.name
}
-func growdatsize(datsizep *int64, s *LSym) {
- datsize := *datsizep
- const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31)
- switch {
- case s.Size < 0:
- Diag("%s: negative size (%d bytes)", s.Name, s.Size)
- case s.Size > cutoff:
- Diag("%s: symbol too large (%d bytes)", s.Name, s.Size)
- case datsize <= cutoff && datsize+s.Size > cutoff:
- Diag("%s: too much data (over %d bytes)", s.Name, cutoff)
- }
- *datsizep = datsize + s.Size
+const cutoff int64 = 2e9 // 2 GB (or so; looks better in errors than 2^31)
+
+func checkdatsize(datsize int64, symn int) {
+ if datsize > cutoff {
+ Diag("too much data in section %v (over %d bytes)", symn, cutoff)
+ }
}
func list2slice(s *LSym) []*LSym {
}
// Sort symbols.
+ var dataMaxAlign [obj.SXREF]int32
var wg sync.WaitGroup
for symn := range data {
symn := symn
wg.Add(1)
go func() {
- data[symn] = dodataSect(symn, data[symn])
+ data[symn], dataMaxAlign[symn] = dodataSect(symn, data[symn])
wg.Done()
}()
}
s.Sect = sect
s.Type = obj.SDATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
+ checkdatsize(datsize, symn)
}
// .got (and .toc on ppc64)
if len(data[obj.SELFGOT]) > 0 {
sect := addsection(&Segdata, ".got", 06)
- sect.Align = maxalign(data[obj.SELFGOT])
+ sect.Align = dataMaxAlign[obj.SELFGOT]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
var toc *LSym
toc.Value = 0x8000
}
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SELFGOT)
sect.Length = uint64(datsize) - sect.Vaddr
}
/* pointer-free data */
sect := addsection(&Segdata, ".noptrdata", 06)
-
- sect.Align = maxalign(data[obj.SNOPTRDATA])
+ sect.Align = dataMaxAlign[obj.SNOPTRDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.noptrdata", 0).Sect = sect
s.Sect = sect
s.Type = obj.SDATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SNOPTRDATA)
sect.Length = uint64(datsize) - sect.Vaddr
hasinitarr := Linkshared
}
if hasinitarr {
sect := addsection(&Segdata, ".init_array", 06)
- sect.Align = maxalign(data[obj.SINITARR])
+ sect.Align = dataMaxAlign[obj.SINITARR]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
for _, s := range data[obj.SINITARR] {
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
+ checkdatsize(datsize, obj.SINITARR)
}
/* data */
sect = addsection(&Segdata, ".data", 06)
- sect.Align = maxalign(data[obj.SDATA])
+ sect.Align = dataMaxAlign[obj.SDATA]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.data", 0).Sect = sect
datsize = aligndatsize(datsize, s)
s.Value = int64(uint64(datsize) - sect.Vaddr)
gc.AddSym(s)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SDATA)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
/* bss */
sect = addsection(&Segdata, ".bss", 06)
- sect.Align = maxalign(data[obj.SBSS])
+ sect.Align = dataMaxAlign[obj.SBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.bss", 0).Sect = sect
datsize = aligndatsize(datsize, s)
s.Value = int64(uint64(datsize) - sect.Vaddr)
gc.AddSym(s)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SBSS)
sect.Length = uint64(datsize) - sect.Vaddr
gc.End(int64(sect.Length))
/* pointer-free bss */
sect = addsection(&Segdata, ".noptrbss", 06)
-
- sect.Align = maxalign(data[obj.SNOPTRBSS])
+ sect.Align = dataMaxAlign[obj.SNOPTRBSS]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.noptrbss", 0).Sect = sect
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
Linklookup(Ctxt, "runtime.end", 0).Sect = sect
-
- // The compiler uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
- if datsize != int64(uint32(datsize)) {
- Diag("data or bss segment too large")
- }
+ checkdatsize(datsize, obj.SNOPTRBSS)
if len(data[obj.STLSBSS]) > 0 {
var sect *Section
datsize = aligndatsize(datsize, s)
s.Sect = sect
s.Value = datsize
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.STLSBSS)
if sect != nil {
sect.Length = uint64(datsize)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
+ checkdatsize(datsize, obj.SELFRXSECT)
}
/* read-only data */
obj.SFUNCTAB,
}
for _, symn := range roSects {
- align := maxalign(data[symn])
+ align := dataMaxAlign[symn]
if sect.Align < align {
sect.Align = align
}
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, symn)
}
sect.Length = uint64(datsize) - sect.Vaddr
obj.SFUNCTABRELRO,
}
for _, symn := range relroSects {
- align := maxalign(data[symn])
+ align := dataMaxAlign[symn]
if sect.Align < align {
sect.Align = align
}
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, symn)
}
sect.Length = uint64(datsize) - sect.Vaddr
/* typelink */
sect = addsection(segro, relro_prefix+".typelink", relro_perms)
- sect.Align = maxalign(data[obj.STYPELINK])
+ sect.Align = dataMaxAlign[obj.STYPELINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.typelink", 0).Sect = sect
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.STYPELINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* itablink */
sect = addsection(segro, relro_prefix+".itablink", relro_perms)
-
- sect.Align = maxalign(data[obj.SITABLINK])
+ sect.Align = dataMaxAlign[obj.SITABLINK]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.itablink", 0).Sect = sect
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SITABLINK)
sect.Length = uint64(datsize) - sect.Vaddr
/* gosymtab */
sect = addsection(segro, relro_prefix+".gosymtab", relro_perms)
-
- sect.Align = maxalign(data[obj.SSYMTAB])
+ sect.Align = dataMaxAlign[obj.SSYMTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.symtab", 0).Sect = sect
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SSYMTAB)
sect.Length = uint64(datsize) - sect.Vaddr
/* gopclntab */
sect = addsection(segro, relro_prefix+".gopclntab", relro_perms)
-
- sect.Align = maxalign(data[obj.SPCLNTAB])
+ sect.Align = dataMaxAlign[obj.SPCLNTAB]
datsize = Rnd(datsize, int64(sect.Align))
sect.Vaddr = uint64(datsize)
Linklookup(Ctxt, "runtime.pclntab", 0).Sect = sect
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
}
+ checkdatsize(datsize, obj.SRODATA)
sect.Length = uint64(datsize) - sect.Vaddr
/* read-only ELF, Mach-O sections */
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
+ checkdatsize(datsize, obj.SELFROSECT)
for _, s := range data[obj.SMACHOPLT] {
sect = addsection(segro, s.Name, 04)
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
+ checkdatsize(datsize, obj.SMACHOPLT)
// 6g uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
if datsize != int64(uint32(datsize)) {
s.Sect = sect
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
- growdatsize(&datsize, s)
+ datsize += s.Size
sect.Length = uint64(datsize) - sect.Vaddr
}
+ checkdatsize(datsize, obj.SDWARFSECT)
if s != nil {
sect = addsection(&Segdwarf, ".debug_info", 04)
s.Type = obj.SRODATA
s.Value = int64(uint64(datsize) - sect.Vaddr)
s.Attr |= AttrLocal
- growdatsize(&datsize, s)
+ datsize += s.Size
}
sect.Length = uint64(datsize) - sect.Vaddr
- }
-
- // The compiler uses 4-byte relocation offsets, so the entire segment must fit in 32 bits.
- if datsize != int64(uint32(datsize)) {
- Diag("dwarf segment too large")
+ checkdatsize(datsize, obj.SDWARFINFO)
}
/* number the sections */
}
}
-func dodataSect(symn int, syms []*LSym) []*LSym {
+func dodataSect(symn int, syms []*LSym) (result []*LSym, maxAlign int32) {
if HEADTYPE == obj.Hdarwin {
// Some symbols may no longer belong in syms
// due to movement in machosymorder.
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Attr |= AttrOnList
- if int64(len(s.P)) > s.Size {
+ switch {
+ case s.Size < int64(len(s.P)):
Diag("%s: initialize bounds (%d < %d)", s.Name, s.Size, len(s.P))
+ case s.Size < 0:
+ Diag("%s: negative size (%d bytes)", s.Name, s.Size)
+ case s.Size > cutoff:
+ Diag("%s: symbol too large (%d bytes)", s.Name, s.Size)
}
symsSort[i] = dataSortKey{
for i, symSort := range symsSort {
syms[i] = symSort.lsym
+ align := symalign(symSort.lsym)
+ if maxAlign < align {
+ maxAlign = align
+ }
}
if Iself && symn == obj.SELFROSECT {
}
}
- return syms
+ return syms, maxAlign
}
// Add buildid to beginning of text segment, on non-ELF systems.