cmd/link: skip gaps between PT_LOAD segments in TestPIESize

There may be gaps between non-writeable and writeable PT_LOAD
segments, and the gaps may be large as the segments may have
large alignment. Don't count those gaps in file size comparison.

Fixes #36023.

Change-Id: I68582bdd0f385ac5c6f87d485d476d06bc96db19
Reviewed-on: https://go-review.googlesource.com/c/go/+/210180
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
diff --git a/src/cmd/link/elf_test.go b/src/cmd/link/elf_test.go
index f0c7872..11a7730 100644
--- a/src/cmd/link/elf_test.go
+++ b/src/cmd/link/elf_test.go
@@ -348,6 +348,9 @@
 			// difference in size of the .got and .plt
 			// sections if they exist.
 			// We ignore unallocated sections.
+			// There may be gaps between non-writeable and
+			// writable PT_LOAD segments. We also skip those
+			// gaps (see issue #36023).
 
 			textsize := func(ef *elf.File, name string) uint64 {
 				for _, s := range ef.Sections {
@@ -383,11 +386,23 @@
 
 			extrasize := func(ef *elf.File) uint64 {
 				var ret uint64
+				// skip unallocated sections
 				for _, s := range ef.Sections {
 					if s.Flags&elf.SHF_ALLOC == 0 {
 						ret += s.Size
 					}
 				}
+				// also skip gaps between PT_LOAD segments
+				for i := range ef.Progs {
+					if i == 0 {
+						continue
+					}
+					p1 := ef.Progs[i-1]
+					p2 := ef.Progs[i]
+					if p1.Type == elf.PT_LOAD && p2.Type == elf.PT_LOAD {
+						ret += p2.Off - p1.Off - p1.Filesz
+					}
+				}
 				return ret
 			}