Just noticed this in passing.
Change-Id: I58fa828ef58598209ed4cbe4abc6f9f02ffc4844
Reviewed-on: https://go-review.googlesource.com/40896
Run-TryBot: Michael Hudson-Doyle <michael.hudson@canonical.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// 0xCC is INT $3 - breakpoint instruction
ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
// to the start of the first text section, even if there are multiple.
if r.Sym.Sect.Name == ".text" {
- o = Symaddr(r.Sym) - int64(Segtext.Sect.Vaddr) + r.Add
+ o = Symaddr(r.Sym) - int64(Segtext.Sections[0].Vaddr) + r.Add
} else {
o = Symaddr(r.Sym) - int64(r.Sym.Sect.Vaddr) + r.Add
}
/* number the sections */
n := int32(1)
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
sect.Extnum = int16(n)
n++
}
- for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrodata.Sections {
sect.Extnum = int16(n)
n++
}
- for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrelrodata.Sections {
sect.Extnum = int16(n)
n++
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
sect.Extnum = int16(n)
n++
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
sect.Extnum = int16(n)
n++
}
// Assign PCs in text segment.
// Could parallelize, by assigning to text
// and then letting threads copy down, but probably not worth it.
- sect := Segtext.Sect
+ sect := Segtext.Sections[0]
sect.Align = int32(Funcalign)
Segtext.Rwx = 05
Segtext.Vaddr = va
Segtext.Fileoff = uint64(HEADR)
- for s := Segtext.Sect; s != nil; s = s.Next {
+ for _, s := range Segtext.Sections {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
va += 32 // room for the "halt sled"
}
- if Segrodata.Sect != nil {
+ if len(Segrodata.Sections) > 0 {
// align to page boundary so as not to mix
// rodata and executable text.
//
Segrodata.Vaddr = va
Segrodata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff
Segrodata.Filelen = 0
- for s := Segrodata.Sect; s != nil; s = s.Next {
+ for _, s := range Segrodata.Sections {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
Segrodata.Length = va - Segrodata.Vaddr
Segrodata.Filelen = Segrodata.Length
}
- if Segrelrodata.Sect != nil {
+ if len(Segrelrodata.Sections) > 0 {
// align to page boundary so as not to mix
// rodata, rel-ro data, and executable text.
va = uint64(Rnd(int64(va), int64(*FlagRound)))
Segrelrodata.Vaddr = va
Segrelrodata.Fileoff = va - Segrodata.Vaddr + Segrodata.Fileoff
Segrelrodata.Filelen = 0
- for s := Segrelrodata.Sect; s != nil; s = s.Next {
+ for _, s := range Segrelrodata.Sections {
va = uint64(Rnd(int64(va), int64(s.Align)))
s.Vaddr = va
va += s.Length
var bss *Section
var noptrbss *Section
var vlen int64
- for s := Segdata.Sect; s != nil; s = s.Next {
+ for i, s := range Segdata.Sections {
if Iself && s.Name == ".tbss" {
continue
}
vlen = int64(s.Length)
- if s.Next != nil && !(Iself && s.Next.Name == ".tbss") {
- vlen = int64(s.Next.Vaddr - s.Vaddr)
+ if i+1 < len(Segdata.Sections) && !(Iself && Segdata.Sections[i+1].Name == ".tbss") {
+ vlen = int64(Segdata.Sections[i+1].Vaddr - s.Vaddr)
}
s.Vaddr = va
va += uint64(vlen)
if Headtype == obj.Hwindows {
Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(PEFILEALIGN)))
}
- for s := Segdwarf.Sect; s != nil; s = s.Next {
+ for i, s := range Segdwarf.Sections {
vlen = int64(s.Length)
- if s.Next != nil {
- vlen = int64(s.Next.Vaddr - s.Vaddr)
+ if i+1 < len(Segdwarf.Sections) {
+ vlen = int64(Segdwarf.Sections[i+1].Vaddr - s.Vaddr)
}
s.Vaddr = va
va += uint64(vlen)
Segdwarf.Filelen = va - Segdwarf.Vaddr
var (
- text = Segtext.Sect
+ text = Segtext.Sections[0]
rodata = ctxt.Syms.Lookup("runtime.rodata", 0).Sect
itablink = ctxt.Syms.Lookup("runtime.itablink", 0).Sect
symtab = ctxt.Syms.Lookup("runtime.symtab", 0).Sect
)
lasttext := text
// Could be multiple .text sections
- for sect := text.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
- lasttext = sect
+ for _, sect := range Segtext.Sections {
+ if sect.Name == ".text" {
+ lasttext = sect
+ }
}
for _, s := range datap {
// If there are multiple text sections, create runtime.text.n for
// their section Vaddr, using n for index
n := 1
- for sect := Segtext.Sect.Next; sect != nil && sect.Name == ".text"; sect = sect.Next {
- symname := fmt.Sprintf("runtime.text.%d", n)
- ctxt.xdefine(symname, obj.STEXT, int64(sect.Vaddr))
- n++
+ for _, sect := range Segtext.Sections[1:] {
+ if sect.Name == ".text" {
+ symname := fmt.Sprintf("runtime.text.%d", n)
+ ctxt.xdefine(symname, obj.STEXT, int64(sect.Vaddr))
+ n++
+ } else {
+ break
+ }
}
ctxt.xdefine("runtime.rodata", obj.SRODATA, int64(rodata.Vaddr))
if *FlagW { // disable dwarf
return
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
h := newPEDWARFSection(ctxt, sect.Name, int64(sect.Length))
fileoff := sect.Vaddr - Segdwarf.Vaddr + Segdwarf.Fileoff
if uint64(h.PointerToRawData) != fileoff {
Cput(0)
}
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
if sect.Name == ".text" {
elfrelocsect(ctxt, sect, ctxt.Textp)
} else {
}
}
- for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrodata.Sections {
elfrelocsect(ctxt, sect, datap)
}
- for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrelrodata.Sections {
elfrelocsect(ctxt, sect, datap)
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
elfrelocsect(ctxt, sect, datap)
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
elfrelocsect(ctxt, sect, dwarfp)
}
}
/* This null SHdr must appear before all others */
elfshname("")
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
// There could be multiple .text sections. Instead check the Elfsect
// field to determine if already has an ElfShdr and if not, create one.
if sect.Name == ".text" {
elfshalloc(sect)
}
}
- for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrodata.Sections {
elfshalloc(sect)
}
- for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrelrodata.Sections {
elfshalloc(sect)
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
elfshalloc(sect)
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
elfshalloc(sect)
}
}
elfreserve := int64(ELFRESERVE)
numtext := int64(0)
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
if sect.Name == ".text" {
numtext++
}
// Additions to the reserved area must be above this line.
elfphload(&Segtext)
- if Segrodata.Sect != nil {
+ if len(Segrodata.Sections) > 0 {
elfphload(&Segrodata)
}
- if Segrelrodata.Sect != nil {
+ if len(Segrelrodata.Sections) > 0 {
elfphload(&Segrelrodata)
elfphrelro(&Segrelrodata)
}
* Thread-local storage segment (really just size).
*/
tlssize := uint64(0)
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
if sect.Name == ".tbss" {
tlssize = sect.Length
}
elfshname(".strtab")
}
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
elfshbits(sect)
}
- for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrodata.Sections {
elfshbits(sect)
}
- for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrelrodata.Sections {
elfshbits(sect)
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
elfshbits(sect)
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
elfshbits(sect)
}
if Linkmode == LinkExternal {
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
elfshreloc(sect)
}
- for sect := Segrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrodata.Sections {
elfshreloc(sect)
}
- for sect := Segrelrodata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segrelrodata.Sections {
elfshreloc(sect)
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
elfshreloc(sect)
}
for _, s := range dwarfp {
)
type Segment struct {
- Rwx uint8 // permission as usual unix bits (5 = r-x etc)
- Vaddr uint64 // virtual address
- Length uint64 // length in memory
- Fileoff uint64 // file offset
- Filelen uint64 // length on disk
- Sect *Section
+ Rwx uint8 // permission as usual unix bits (5 = r-x etc)
+ Vaddr uint64 // virtual address
+ Length uint64 // length in memory
+ Fileoff uint64 // file offset
+ Filelen uint64 // length on disk
+ Sections []*Section
}
type Section struct {
Name string
Vaddr uint64
Length uint64
- Next *Section
Seg *Segment
Elfsect *ElfShdr
Reloff uint64
}
func addsection(seg *Segment, name string, rwx int) *Section {
- var l **Section
-
- for l = &seg.Sect; *l != nil; l = &(*l).Next {
- }
sect := new(Section)
sect.Rwx = uint8(rwx)
sect.Name = name
sect.Seg = seg
sect.Align = int32(SysArch.PtrSize) // everything is at least pointer-aligned
- *l = sect
+ seg.Sections = append(seg.Sections, sect)
return sect
}
n := 0
// Generate base addresses for all text sections if there are multiple
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
if n == 0 {
n++
continue
ms.prot2 = 5
}
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
machoshbits(ctxt, ms, sect, "__TEXT")
}
ms.prot2 = 3
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
machoshbits(ctxt, ms, sect, "__DATA")
}
ms.fileoffset = Segdwarf.Fileoff
ms.filesize = Segdwarf.Filelen
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
machoshbits(ctxt, ms, sect, "__DWARF")
}
}
Cput(0)
}
- machorelocsect(ctxt, Segtext.Sect, ctxt.Textp)
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
+ machorelocsect(ctxt, Segtext.Sections[0], ctxt.Textp)
+ for _, sect := range Segtext.Sections[1:] {
machorelocsect(ctxt, sect, datap)
}
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
machorelocsect(ctxt, sect, datap)
}
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
machorelocsect(ctxt, sect, dwarfp)
}
}
}
peemitsectreloc(text, func() int {
- n := perelocsect(ctxt, Segtext.Sect, ctxt.Textp, Segtext.Vaddr)
- for sect := Segtext.Sect.Next; sect != nil; sect = sect.Next {
+ n := perelocsect(ctxt, Segtext.Sections[0], ctxt.Textp, Segtext.Vaddr)
+ for _, sect := range Segtext.Sections[1:] {
n += perelocsect(ctxt, sect, datap, Segtext.Vaddr)
}
return n
peemitsectreloc(data, func() int {
var n int
- for sect := Segdata.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdata.Sections {
n += perelocsect(ctxt, sect, datap, Segdata.Vaddr)
}
return n
})
dwarfLoop:
- for sect := Segdwarf.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segdwarf.Sections {
for i, name := range shNames {
if sect.Name == name {
peemitsectreloc(&sh[i], func() int {
t.Attr |= AttrReachable
nsections := int64(0)
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range Segtext.Sections {
if sect.Name == ".text" {
nsections++
} else {
// order of creation starting with 1. These symbols provide the section's
// address after relocation by the linker.
- textbase := Segtext.Sect.Vaddr
- for sect := Segtext.Sect; sect != nil; sect = sect.Next {
+ textbase := Segtext.Sections[0].Vaddr
+ for _, sect := range Segtext.Sections {
if sect.Name != ".text" {
break
}
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
ld.Asmbelfsetup()
}
- for sect := ld.Segtext.Sect; sect != nil; sect = sect.Next {
+ for _, sect := range ld.Segtext.Sections {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// Handle additional text sections with Codeblk
if sect.Name == ".text" {
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Codeblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}
ld.Asmbelfsetup()
}
- sect := ld.Segtext.Sect
+ sect := ld.Segtext.Sections[0]
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
// 0xCC is INT $3 - breakpoint instruction
ld.CodeblkPad(ctxt, int64(sect.Vaddr), int64(sect.Length), []byte{0xCC})
- for sect = sect.Next; sect != nil; sect = sect.Next {
+ for _, sect = range ld.Segtext.Sections[1:] {
ld.Cseek(int64(sect.Vaddr - ld.Segtext.Vaddr + ld.Segtext.Fileoff))
ld.Datblk(ctxt, int64(sect.Vaddr), int64(sect.Length))
}