func readsym(b *bufio.Reader, s *liblink.LSym) { if !undef[s] { panic("double-def") } delete(undef, s) s.Name = rdstring(b) s.Extname = rdstring(b) s.Type_ = int16(rdint(b)) s.Version = int16(rdint(b)) s.Dupok = uint8(rdint(b)) s.External = uint8(rdint(b)) s.Nosplit = uint8(rdint(b)) s.Reachable = uint8(rdint(b)) s.Cgoexport = uint8(rdint(b)) s.Special = uint8(rdint(b)) s.Stkcheck = uint8(rdint(b)) s.Hide = uint8(rdint(b)) s.Leaf = uint8(rdint(b)) s.Fnptr = uint8(rdint(b)) s.Seenglobl = uint8(rdint(b)) s.Onlist = uint8(rdint(b)) s.Symid = int16(rdint(b)) s.Dynid = int32(rdint(b)) s.Sig = int32(rdint(b)) s.Plt = int32(rdint(b)) s.Got = int32(rdint(b)) s.Align = int32(rdint(b)) s.Elfsym = int32(rdint(b)) s.Args = int32(rdint(b)) s.Locals = int32(rdint(b)) s.Value = rdint(b) s.Size = rdint(b) hashed[rdsym(b)] = true s.Allsym = rdsym(b) s.Next = rdsym(b) s.Sub = rdsym(b) s.Outer = rdsym(b) s.Gotype = rdsym(b) s.Reachparent = rdsym(b) s.Queue = rdsym(b) s.File = rdstring(b) s.Dynimplib = rdstring(b) s.Dynimpvers = rdstring(b) s.Text = rdprog(b) s.Etext = rdprog(b) n := int(rdint(b)) if n > 0 { s.P = make([]byte, n) io.ReadFull(b, s.P) } s.R = make([]liblink.Reloc, int(rdint(b))) for i := range s.R { r := &s.R[i] r.Off = int32(rdint(b)) r.Siz = uint8(rdint(b)) r.Done = uint8(rdint(b)) r.Type_ = int32(rdint(b)) r.Add = rdint(b) r.Xadd = rdint(b) r.Sym = rdsym(b) r.Xsym = rdsym(b) } }
func progedit(ctxt *liblink.Link, p *liblink.Prog) { var literal string var s *liblink.LSym p.From.Class = 0 p.To.Class = 0 // Rewrite BR/BL to symbol as D_BRANCH. switch p.As { case ABR, ABL, ARETURN, ADUFFZERO, ADUFFCOPY: if p.To.Sym != nil { p.To.Type_ = D_BRANCH } break } // Rewrite float constants to values stored in memory. switch p.As { case AFMOVS: if p.From.Type_ == D_FCONST { var i32 uint32 var f32 float32 f32 = float32(p.From.U.Dval) i32 = math.Float32bits(f32) literal = fmt.Sprintf("$f32.%08x", i32) s = liblink.Linklookup(ctxt, literal, 0) s.Size = 4 p.From.Type_ = D_OREG p.From.Sym = s p.From.Name = D_EXTERN p.From.Offset = 0 } case AFMOVD: if p.From.Type_ == D_FCONST { var i64 uint64 i64 = math.Float64bits(p.From.U.Dval) literal = fmt.Sprintf("$f64.%016x", i64) s = liblink.Linklookup(ctxt, literal, 0) s.Size = 8 p.From.Type_ = D_OREG p.From.Sym = s p.From.Name = D_EXTERN p.From.Offset = 0 } // Put >32-bit constants in memory and load them case AMOVD: if p.From.Type_ == D_CONST && p.From.Name == D_NONE && p.From.Reg == NREG && int64(int32(p.From.Offset)) != p.From.Offset { literal = fmt.Sprintf("$i64.%016x", uint64(p.From.Offset)) s = liblink.Linklookup(ctxt, literal, 0) s.Size = 8 p.From.Type_ = D_OREG p.From.Sym = s p.From.Name = D_EXTERN p.From.Offset = 0 } } // Rewrite SUB constants into ADD. switch p.As { case ASUBC: if p.From.Type_ == D_CONST { p.From.Offset = -p.From.Offset p.As = AADDC } case ASUBCCC: if p.From.Type_ == D_CONST { p.From.Offset = -p.From.Offset p.As = AADDCCC } case ASUB: if p.From.Type_ == D_CONST { p.From.Offset = -p.From.Offset p.As = AADD } break } }