aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cmd/link/internal/ld/data.go68
-rw-r--r--src/cmd/link/internal/ld/main.go3
2 files changed, 42 insertions, 29 deletions
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()