diff --git a/src/cmd/link/internal/ld/data.go b/src/cmd/link/internal/ld/data.go index 3e4773102d..184e8158fd 100644 --- a/src/cmd/link/internal/ld/data.go +++ b/src/cmd/link/internal/ld/data.go @@ -1903,12 +1903,15 @@ func assignAddress(ctxt *Link, sect *sym.Section, n int, s *sym.Symbol, va uint6 return sect, n, va } -// assign addresses -func (ctxt *Link) address() { +// address assigns virtual addresses to all segments and sections and +// returns all segments in file order. +func (ctxt *Link) address() []*sym.Segment { + var order []*sym.Segment // Layout order + va := uint64(*FlagTextAddr) + order = append(order, &Segtext) Segtext.Rwx = 05 Segtext.Vaddr = va - Segtext.Fileoff = uint64(HEADR) for _, s := range Segtext.Sections { va = uint64(Rnd(int64(va), int64(s.Align))) s.Vaddr = va @@ -1916,7 +1919,6 @@ func (ctxt *Link) address() { } Segtext.Length = va - uint64(*FlagTextAddr) - Segtext.Filelen = Segtext.Length if ctxt.HeadType == objabi.Hnacl { va += 32 // room for the "halt sled" } @@ -1937,13 +1939,9 @@ func (ctxt *Link) address() { // writable even for this short period. va = uint64(Rnd(int64(va), int64(*FlagRound))) + order = append(order, &Segrodata) Segrodata.Rwx = 04 Segrodata.Vaddr = va - Segrodata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff - Segrodata.Filelen = 0 - if ctxt.HeadType == objabi.Hwindows { - Segrodata.Fileoff = Segtext.Fileoff + uint64(Rnd(int64(Segtext.Length), PEFILEALIGN)) - } for _, s := range Segrodata.Sections { va = uint64(Rnd(int64(va), int64(s.Align))) s.Vaddr = va @@ -1951,17 +1949,15 @@ func (ctxt *Link) address() { } Segrodata.Length = va - Segrodata.Vaddr - Segrodata.Filelen = Segrodata.Length } 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))) + order = append(order, &Segrelrodata) Segrelrodata.Rwx = 06 Segrelrodata.Vaddr = va - Segrelrodata.Fileoff = va - Segrodata.Vaddr + Segrodata.Fileoff - Segrelrodata.Filelen = 0 for _, s := range Segrelrodata.Sections { va = uint64(Rnd(int64(va), int64(s.Align))) s.Vaddr = va @@ -1969,20 +1965,12 @@ func (ctxt *Link) address() { } Segrelrodata.Length = va - Segrelrodata.Vaddr - Segrelrodata.Filelen = Segrelrodata.Length } va = uint64(Rnd(int64(va), int64(*FlagRound))) + order = append(order, &Segdata) Segdata.Rwx = 06 Segdata.Vaddr = va - Segdata.Fileoff = va - Segtext.Vaddr + Segtext.Fileoff - Segdata.Filelen = 0 - if ctxt.HeadType == objabi.Hwindows { - Segdata.Fileoff = Segrodata.Fileoff + uint64(Rnd(int64(Segrodata.Length), PEFILEALIGN)) - } - if ctxt.HeadType == objabi.Hplan9 { - Segdata.Fileoff = Segtext.Fileoff + Segtext.Filelen - } var data *sym.Section var noptr *sym.Section var bss *sym.Section @@ -2012,16 +2000,14 @@ func (ctxt *Link) address() { } } + // Assign Segdata's Filelen omitting the BSS. We do this here + // simply because right now we know where the BSS starts. Segdata.Filelen = bss.Vaddr - Segdata.Vaddr va = uint64(Rnd(int64(va), int64(*FlagRound))) + order = append(order, &Segdwarf) Segdwarf.Rwx = 06 Segdwarf.Vaddr = va - Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), int64(*FlagRound))) - Segdwarf.Filelen = 0 - if ctxt.HeadType == objabi.Hwindows { - Segdwarf.Fileoff = Segdata.Fileoff + uint64(Rnd(int64(Segdata.Filelen), PEFILEALIGN)) - } for i, s := range Segdwarf.Sections { vlen := int64(s.Length) if i+1 < len(Segdwarf.Sections) { @@ -2035,8 +2021,6 @@ func (ctxt *Link) address() { Segdwarf.Length = va - Segdwarf.Vaddr } - Segdwarf.Filelen = va - Segdwarf.Vaddr - var ( text = Segtext.Sections[0] rodata = ctxt.Syms.Lookup("runtime.rodata", 0).Sect @@ -2123,6 +2107,34 @@ func (ctxt *Link) address() { ctxt.xdefine("runtime.noptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr)) ctxt.xdefine("runtime.enoptrbss", sym.SNOPTRBSS, int64(noptrbss.Vaddr+noptrbss.Length)) ctxt.xdefine("runtime.end", sym.SBSS, int64(Segdata.Vaddr+Segdata.Length)) + + return order +} + +// layout assigns file offsets and lengths to the segments in order. +func (ctxt *Link) layout(order []*sym.Segment) { + var prev *sym.Segment + for _, seg := range order { + if prev == nil { + seg.Fileoff = uint64(HEADR) + } else { + switch ctxt.HeadType { + default: + seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), int64(*FlagRound))) + case objabi.Hwindows: + seg.Fileoff = prev.Fileoff + uint64(Rnd(int64(prev.Filelen), PEFILEALIGN)) + case objabi.Hplan9: + seg.Fileoff = prev.Fileoff + prev.Filelen + } + } + if seg != &Segdata { + // Link.address already set Segdata.Filelen to + // account for BSS. + seg.Filelen = seg.Length + } + prev = seg + } + } // add a trampoline with symbol s (to be laid down after the current function) diff --git a/src/cmd/link/internal/ld/main.go b/src/cmd/link/internal/ld/main.go index bfa3f70a9e..23dfa277d0 100644 --- a/src/cmd/link/internal/ld/main.go +++ b/src/cmd/link/internal/ld/main.go @@ -224,8 +224,9 @@ func Main(arch *sys.Arch, theArch Arch) { ctxt.typelink() ctxt.symtab() ctxt.dodata() - ctxt.address() + order := ctxt.address() ctxt.reloc() + ctxt.layout(order) thearch.Asmb(ctxt) ctxt.undef() ctxt.hostlink()