wasm: include DWARF information in Wasm builds

This change adds DWARF debug information to Wasm binaries, which was
not present previously.

WIP: Some debug information is written correctly, but all locations are set to 0,
     so debugging does not yet work in Chrome.
     I opened this change so that other people could look into this.
     See the discussion on GitHub for more details on this.

Fixes #33503

Change-Id: I8cc03eb398da39dd19c41b9ce2bb803ed9bfb40c
diff --git a/src/cmd/link/internal/ld/asmb.go b/src/cmd/link/internal/ld/asmb.go
index fda0439..d91488d 100644
--- a/src/cmd/link/internal/ld/asmb.go
+++ b/src/cmd/link/internal/ld/asmb.go
@@ -73,6 +73,14 @@
 	wg.Wait()
 }
 
+func GetDwarfSections(ctxt *Link, ldr *loader.Loader) [][]loader.Sym {
+	var sects [][]loader.Sym
+	for _, info := range dwarfp {
+		sects = append(sects, info.syms)
+	}
+	return sects
+}
+
 // Assembling the binary is broken into two steps:
 //  - writing out the code/data/dwarf Segments
 //  - writing out the architecture specific pieces.
diff --git a/src/cmd/link/internal/ld/dwarf.go b/src/cmd/link/internal/ld/dwarf.go
index 2ab9a55..3fd8f82 100644
--- a/src/cmd/link/internal/ld/dwarf.go
+++ b/src/cmd/link/internal/ld/dwarf.go
@@ -1658,7 +1658,7 @@
 	if *FlagS && ctxt.HeadType != objabi.Hdarwin {
 		return false
 	}
-	if ctxt.HeadType == objabi.Hplan9 || ctxt.HeadType == objabi.Hjs {
+	if ctxt.HeadType == objabi.Hplan9 {
 		return false
 	}
 
@@ -1953,7 +1953,7 @@
 
 // dwarfGenerateDebugSyms constructs debug_line, debug_frame, and
 // debug_loc. It also writes out the debug_info section using symbols
-// generated in dwarfGenerateDebugInfo2.
+// generated in dwarfGenerateDebugInfo.
 func dwarfGenerateDebugSyms(ctxt *Link) {
 	if !dwarfEnabled(ctxt) {
 		return
diff --git a/src/cmd/link/internal/wasm/asm.go b/src/cmd/link/internal/wasm/asm.go
index 31851fb..35c61c3 100644
--- a/src/cmd/link/internal/wasm/asm.go
+++ b/src/cmd/link/internal/wasm/asm.go
@@ -6,11 +6,14 @@
 
 import (
 	"bytes"
+	"cmd/internal/dwarf"
 	"cmd/internal/objabi"
 	"cmd/link/internal/ld"
 	"cmd/link/internal/loader"
 	"cmd/link/internal/sym"
+	"fmt"
 	"io"
+	"log"
 	"regexp"
 )
 
@@ -216,6 +219,7 @@
 	writeCodeSec(ctxt, fns)
 	writeDataSec(ctxt)
 	writeProducerSec(ctxt)
+	writeDwarfSec(ctxt, ldr)
 	if !*ld.FlagS {
 		writeNameSec(ctxt, len(hostImports), fns)
 	}
@@ -519,6 +523,39 @@
 	writeSecSize(ctxt, sizeOffset)
 }
 
+func writeDwarfSec(ctxt *ld.Link, ldr *loader.Loader) {
+	dwarfp := ld.GetDwarfSections(ctxt, ldr)
+	for _, sec := range dwarfp {
+		if len(sec) == 0 {
+			continue
+		}
+		secSym := sec[0]
+		var dataSyms []loader.Sym
+		if len(sec) > 1 {
+			dataSyms = sec[1:]
+		}
+		secName := ldr.SymName(secSym)
+		secOffset := writeSecHeader(ctxt, sectionCustom)
+		writeName(ctxt.Out, secName)
+
+		if secName == ".debug_abbrev" {
+			// why is debug_abbrev so special?
+			abbrev := dwarf.GetAbbrev()
+			if _, err := ctxt.Out.Write(abbrev); err != nil {
+				fmt.Println(err)
+			}
+		} else {
+			for _, dataSym := range dataSyms {
+				data := ldr.Data(dataSym)
+				if _, err := ctxt.Out.Write(data); err != nil {
+					log.Println(err)
+				}
+			}
+		}
+		writeSecSize(ctxt, secOffset)
+	}
+}
+
 var nameRegexp = regexp.MustCompile(`[^\w\.]`)
 
 // writeNameSec writes an optional section that assigns names to the functions declared by the "func" section.