From d697a9d5d7d75cecd8d49b95ed9a0d1f2f3e8ed4 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Mon, 18 Apr 2016 16:12:48 +1000 Subject: debug/pe: introduce StringTable type PE specification requires that long section and symbol names are stored in PE string table. Introduce StringTable that implements this functionality. Only string table reading is implemented. Updates #15345 Change-Id: Ib9638617f2ab1881ad707111d96fc68b0e47340e Reviewed-on: https://go-review.googlesource.com/22181 TryBot-Result: Gobot Gobot Reviewed-by: Alex Brainman --- src/debug/pe/string.go | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/debug/pe/string.go (limited to 'src/debug/pe/string.go') diff --git a/src/debug/pe/string.go b/src/debug/pe/string.go new file mode 100644 index 0000000000..f0928d09c5 --- /dev/null +++ b/src/debug/pe/string.go @@ -0,0 +1,64 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package pe + +import ( + "encoding/binary" + "fmt" + "io" +) + +// TODO(brainman): return error from cstring and see what errors we get and what to do about it + +// cstring converts ASCII byte sequence b to string. It stops once it finds 0. +func cstring(b []byte) string { + var i int + for i = 0; i < len(b) && b[i] != 0; i++ { + } + return string(b[:i]) +} + +// StringTable is a COFF string table. +type StringTable []byte + +func readStringTable(fh *FileHeader, r io.ReadSeeker) (StringTable, error) { + // COFF string table is located right after COFF symbol table. + offset := fh.PointerToSymbolTable + COFFSymbolSize*fh.NumberOfSymbols + _, err := r.Seek(int64(offset), io.SeekStart) + if err != nil { + return nil, fmt.Errorf("fail to seek to string table: %v", err) + } + var l uint32 + err = binary.Read(r, binary.LittleEndian, &l) + if err != nil { + return nil, fmt.Errorf("fail to read string table length: %v", err) + } + // string table length includes itself + if l <= 4 { + return nil, nil + } + l -= 4 + buf := make([]byte, l) + _, err = io.ReadFull(r, buf) + if err != nil { + return nil, fmt.Errorf("fail to read string table: %v", err) + } + return StringTable(buf), nil +} + +// TODO(brainman): decide if start parameter should be int instead of uint32 + +// String extracts string from COFF string table st at offset start. +func (st StringTable) String(start uint32) (string, error) { + // start includes 4 bytes of string table length + if start < 4 { + return "", fmt.Errorf("offset %d is before the start of string table", start) + } + start -= 4 + if int(start) > len(st) { + return "", fmt.Errorf("offset %d is beyond the end of string table", start) + } + return cstring(st[start:]), nil +} -- cgit v1.3 From 11f1041022e001869de076699f297b28d25fc558 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Thu, 21 Apr 2016 10:42:25 +1000 Subject: debug/pe: update cstring documentation Updates #15345 Change-Id: If1fca1f6042571cb0ac689bbb3c294309dd6e7b4 Reviewed-on: https://go-review.googlesource.com/22331 Reviewed-by: Ian Lance Taylor Run-TryBot: Alex Brainman TryBot-Result: Gobot Gobot --- src/debug/pe/string.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/debug/pe/string.go') diff --git a/src/debug/pe/string.go b/src/debug/pe/string.go index f0928d09c5..e00bd97dd4 100644 --- a/src/debug/pe/string.go +++ b/src/debug/pe/string.go @@ -10,9 +10,8 @@ import ( "io" ) -// TODO(brainman): return error from cstring and see what errors we get and what to do about it - -// cstring converts ASCII byte sequence b to string. It stops once it finds 0. +// cstring converts ASCII byte sequence b to string. +// It stops once it finds 0 or reaches end of b. func cstring(b []byte) string { var i int for i = 0; i < len(b) && b[i] != 0; i++ { -- cgit v1.3