1
2
3
4
5 package ld
6
7 import (
8 "cmd/internal/sys"
9 "cmd/link/internal/loader"
10 "cmd/link/internal/sym"
11 )
12
13 var sehp struct {
14 pdata []sym.LoaderSym
15 xdata []sym.LoaderSym
16 }
17
18 func writeSEH(ctxt *Link) {
19 switch ctxt.Arch.Family {
20 case sys.AMD64:
21 writeSEHAMD64(ctxt)
22 }
23 }
24
25 func writeSEHAMD64(ctxt *Link) {
26 ldr := ctxt.loader
27 mkSecSym := func(name string, kind sym.SymKind) *loader.SymbolBuilder {
28 s := ldr.CreateSymForUpdate(name, 0)
29 s.SetType(kind)
30 s.SetAlign(4)
31 return s
32 }
33 pdata := mkSecSym(".pdata", sym.SSEHSECT)
34 xdata := mkSecSym(".xdata", sym.SSEHSECT)
35
36
37
38
39
40
41 uwcache := make(map[string]int64)
42 for _, s := range ctxt.Textp {
43 if fi := ldr.FuncInfo(s); !fi.Valid() {
44 continue
45 }
46 uw := ldr.SEHUnwindSym(s)
47 if uw == 0 {
48 continue
49 }
50 name := ctxt.SymName(uw)
51 off, cached := uwcache[name]
52 if !cached {
53 off = xdata.Size()
54 uwcache[name] = off
55 xdata.AddBytes(ldr.Data(uw))
56
57
58 rels := ldr.Relocs(uw)
59 for i := 0; i < rels.Count(); i++ {
60 r := rels.At(i)
61 rel, _ := xdata.AddRel(r.Type())
62 rel.SetOff(int32(off) + r.Off())
63 rel.SetSiz(r.Siz())
64 rel.SetSym(r.Sym())
65 rel.SetAdd(r.Add())
66 }
67 }
68
69
70
71 pdata.AddPEImageRelativeAddrPlus(ctxt.Arch, s, 0)
72 pdata.AddPEImageRelativeAddrPlus(ctxt.Arch, s, ldr.SymSize(s))
73 pdata.AddPEImageRelativeAddrPlus(ctxt.Arch, xdata.Sym(), off)
74 }
75 sehp.pdata = append(sehp.pdata, pdata.Sym())
76 sehp.xdata = append(sehp.xdata, xdata.Sym())
77 }
78
View as plain text