func (cp *ConstantPool) readConstant(c *Constant, br *binary.BinaryReader) error { if err := br.ReadInterface(&c.Tag); err != nil { return err } else { switch c.Tag { case CONSTANT_String: fallthrough case CONSTANT_MethodType: fallthrough case CONSTANT_Class: return br.ReadInterface(&c.Index[0]) case CONSTANT_Fieldref: fallthrough case CONSTANT_Methodref: fallthrough case CONSTANT_NameAndType: fallthrough case CONSTANT_InvokeDynamic: fallthrough case CONSTANT_InterfaceMethodref: if err := br.ReadInterface(&c.Index[0]); err != nil { return err } else { return br.ReadInterface(&c.Index[1]) } case CONSTANT_Integer: var v int32 return br.ReadInterface(&v) case CONSTANT_Float: var v float32 return br.ReadInterface(&v) case CONSTANT_Long: var v int64 return br.ReadInterface(&v) case CONSTANT_Double: var v float64 return br.ReadInterface(&v) case CONSTANT_Utf8: var length u2 if err := br.ReadInterface(&length); err != nil { return err } else if d, err := br.Read(int(length)); err != nil { return err } else { c.Value = string(d) } case CONSTANT_MethodHandle: var ref_kind u1 if err := br.ReadInterface(&ref_kind); err != nil { return err } else { c.Index[0] = u2(ref_kind) return br.ReadInterface(&c.Index[1]) } default: return errors.New(fmt.Sprintf("Unimplemented tag: %d", c.Tag)) } } return nil }
func (mh *MetadataHeader) MetadataUtil(br *binary.BinaryReader) (*MetadataUtil, error) { var ( ret MetadataUtil ) off, err := br.Seek(0, 1) if err != nil { return nil, err } base := off for _, h := range mh.StreamHeaders { switch h.Name { case "#~": off += int64(h.Offset) case "#Strings": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.StringHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.StringHeap.Rows = h.Size case "#Blob": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.BlobHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.BlobHeap.Rows = h.Size case "#GUID": if _, err := br.Seek(base+int64(h.Offset), 0); err != nil { return nil, err } else if ret.GuidHeap.data, err = br.Read(int(h.Size)); err != nil { return nil, err } ret.GuidHeap.Rows = h.Size } } if _, err := br.Seek(off, 0); err != nil { return nil, err } h := hash_tilde_stream_header{} if err := br.ReadInterface(&h); err != nil { return nil, err } if h.HeapSizes&bit_stringHeapIndexSize != 0 { ret.StringHeap.RowSize = 4 } else { ret.StringHeap.RowSize = 2 } if h.HeapSizes&bit_blobHeapIndexSize != 0 { ret.BlobHeap.RowSize = 4 } else { ret.BlobHeap.RowSize = 2 } if h.HeapSizes&bit_guidHeapIndexSize != 0 { ret.GuidHeap.RowSize = 4 } else { ret.GuidHeap.RowSize = 2 } for i := range ret.Tables { if valid := (h.Valid >> uint(i)) & 1; valid == 0 { continue } if ret.Tables[i].Rows, err = br.Uint32(); err != nil { return nil, err } ret.Tables[i].RowType = table_row_type_lut[i] } for i := range ret.Tables { if ret.Tables[i].Rows == 0 { continue } size, err := ret.Size(ret.Tables[i].RowType) if err != nil { return nil, err } ret.Tables[i].RowSize = uint32(size) if ret.Tables[i].data, err = br.Read(int(ret.Tables[i].RowSize * ret.Tables[i].Rows)); err != nil { return nil, err } } return &ret, nil }
func (ie *InfoEntry) data(form DW_FORM, br binary.BinaryReader) interface{} { if form == DW_FORM_ref_addr && ie.header.Version < 3 { form = DW_FORM_addr } switch form { case DW_FORM_flag_present: return true case DW_FORM_exprloc, DW_FORM_block: var size LEB128 br.ReadInterface(&size) r, _ := br.Read(int(size)) return r case DW_FORM_block1: size, _ := br.Uint8() r, _ := br.Read(int(size)) return r case DW_FORM_block2: size, _ := br.Uint16() r, _ := br.Read(int(size)) return r case DW_FORM_block4: size, _ := br.Uint32() r, _ := br.Read(int(size)) return r case DW_FORM_addr: if ie.header.AddressSize == 8 { v, _ := br.Uint64() return v } else { v, _ := br.Uint32() return uint64(v) } case DW_FORM_ref_addr, DW_FORM_strp, DW_FORM_sec_offset: if ie.header.is64 { v, _ := br.Uint64() return v } else { v, _ := br.Uint32() return uint64(v) } case DW_FORM_ref1, DW_FORM_flag, DW_FORM_data1: v, _ := br.Uint8() return uint64(v) case DW_FORM_ref2, DW_FORM_data2: v, _ := br.Uint16() return uint64(v) case DW_FORM_ref4, DW_FORM_data4: v, _ := br.Uint32() return uint64(v) case DW_FORM_ref8, DW_FORM_data8: v, _ := br.Uint64() return v case DW_FORM_sdata, DW_FORM_udata: var r LEB128 br.ReadInterface(&r) return uint64(r) case DW_FORM_string: buf := make([]byte, 4096) for i := range buf { if v, err := br.Uint8(); err != nil { return err } else if v == 0 { buf = buf[:i] break } else { buf[i] = byte(v) } } return string(buf) } panic(fmt.Errorf("Unimplemented format: %s", form)) }