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
}
Segtext.Length = va - uint64(*FlagTextAddr)
- Segtext.Filelen = Segtext.Length
if ctxt.HeadType == objabi.Hnacl {
va += 32 // room for the "halt sled"
}
// 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
}
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
}
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
}
}
+ // 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) {
Segdwarf.Length = va - Segdwarf.Vaddr
}
- Segdwarf.Filelen = va - Segdwarf.Vaddr
-
var (
text = Segtext.Sections[0]
rodata = ctxt.Syms.Lookup("runtime.rodata", 0).Sect
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)