// dname dumps a reflect.name for a struct field or method. func dname(s *Sym, ot int, name, tag string, pkg *Pkg, exported bool) int { if len(name) > 1<<16-1 { Fatalf("name too long: %s", name) } if len(tag) > 1<<16-1 { Fatalf("tag too long: %s", tag) } // Encode name and tag. See reflect/type.go for details. var bits byte l := 1 + 2 + len(name) if exported { bits |= 1 << 0 } if len(tag) > 0 { l += 2 + len(tag) bits |= 1 << 1 } if pkg != nil { bits |= 1 << 2 } b := make([]byte, l) b[0] = bits b[1] = uint8(len(name) >> 8) b[2] = uint8(len(name)) copy(b[3:], name) if len(tag) > 0 { tb := b[3+len(name):] tb[0] = uint8(len(tag) >> 8) tb[1] = uint8(len(tag)) copy(tb[2:], tag) } // Very few names require a pkgPath *string (only those // defined in a different package than their type). So if // there is no pkgPath, we treat the name contents as string // data that duplicates across packages. var bsym *obj.LSym if pkg == nil { _, bsym = stringsym(string(b)) } else { // Write out data as "type.." to signal two things to the // linker, first that when dynamically linking, the symbol // should be moved to a relro section, and second that the // contents should not be decoded as a type. bsymname := fmt.Sprintf(`type..methodname."".%d`, dnameCount) dnameCount++ bsym = obj.Linklookup(Ctxt, bsymname, 0) bsym.P = b boff := len(b) boff = int(Rnd(int64(boff), int64(Widthptr))) boff = dgopkgpathLSym(bsym, boff, pkg) ggloblLSym(bsym, int32(boff), obj.RODATA|obj.LOCAL) } ot = dsymptrLSym(Linksym(s), ot, bsym, 0) return ot }