]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libgo/go/debug/pe/file.go
libgo: Update to current sources.
[thirdparty/gcc.git] / libgo / go / debug / pe / file.go
index 6b98a5f45b9b9e12fb5d44b6047309b00ceb3ed0..f521566efa7abb5a8c33e172f89afb2618af0b3f 100644 (file)
@@ -19,6 +19,7 @@ import (
 type File struct {
        FileHeader
        Sections []*Section
+       Symbols  []*Symbol
 
        closer io.Closer
 }
@@ -49,6 +50,14 @@ type Section struct {
        sr *io.SectionReader
 }
 
+type Symbol struct {
+       Name          string
+       Value         uint32
+       SectionNumber int16
+       Type          uint16
+       StorageClass  uint8
+}
+
 type ImportDirectory struct {
        OriginalFirstThunk uint32
        TimeDateStamp      uint32
@@ -122,12 +131,13 @@ func NewFile(r io.ReaderAt) (*File, error) {
        }
        var base int64
        if dosheader[0] == 'M' && dosheader[1] == 'Z' {
+               signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
                var sign [4]byte
-               r.ReadAt(sign[0:], int64(dosheader[0x3c]))
+               r.ReadAt(sign[:], signoff)
                if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) {
                        return nil, errors.New("Invalid PE File Format.")
                }
-               base = int64(dosheader[0x3c]) + 4
+               base = signoff + 4
        } else {
                base = int64(0)
        }
@@ -138,16 +148,52 @@ func NewFile(r io.ReaderAt) (*File, error) {
        if f.FileHeader.Machine != IMAGE_FILE_MACHINE_UNKNOWN && f.FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && f.FileHeader.Machine != IMAGE_FILE_MACHINE_I386 {
                return nil, errors.New("Invalid PE File Format.")
        }
-       // get symbol string table
-       sr.Seek(int64(f.FileHeader.PointerToSymbolTable+18*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
-       var l uint32
-       if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
-               return nil, err
-       }
-       ss := make([]byte, l)
-       if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+18*f.FileHeader.NumberOfSymbols)); err != nil {
-               return nil, err
+
+       var ss []byte
+       if f.FileHeader.NumberOfSymbols > 0 {
+               // Get COFF string table, which is located at the end of the COFF symbol table.
+               sr.Seek(int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols), os.SEEK_SET)
+               var l uint32
+               if err := binary.Read(sr, binary.LittleEndian, &l); err != nil {
+                       return nil, err
+               }
+               ss = make([]byte, l)
+               if _, err := r.ReadAt(ss, int64(f.FileHeader.PointerToSymbolTable+COFFSymbolSize*f.FileHeader.NumberOfSymbols)); err != nil {
+                       return nil, err
+               }
+
+               // Process COFF symbol table.
+               sr.Seek(int64(f.FileHeader.PointerToSymbolTable), os.SEEK_SET)
+               aux := uint8(0)
+               for i := 0; i < int(f.FileHeader.NumberOfSymbols); i++ {
+                       cs := new(COFFSymbol)
+                       if err := binary.Read(sr, binary.LittleEndian, cs); err != nil {
+                               return nil, err
+                       }
+                       if aux > 0 {
+                               aux--
+                               continue
+                       }
+                       var name string
+                       if cs.Name[0] == 0 && cs.Name[1] == 0 && cs.Name[2] == 0 && cs.Name[3] == 0 {
+                               si := int(binary.LittleEndian.Uint32(cs.Name[4:]))
+                               name, _ = getString(ss, si)
+                       } else {
+                               name = cstring(cs.Name[:])
+                       }
+                       aux = cs.NumberOfAuxSymbols
+                       s := &Symbol{
+                               Name:          name,
+                               Value:         cs.Value,
+                               SectionNumber: cs.SectionNumber,
+                               Type:          cs.Type,
+                               StorageClass:  cs.StorageClass,
+                       }
+                       f.Symbols = append(f.Symbols, s)
+               }
        }
+
+       // Process sections.
        sr.Seek(base, os.SEEK_SET)
        binary.Read(sr, binary.LittleEndian, &f.FileHeader)
        sr.Seek(int64(f.FileHeader.SizeOfOptionalHeader), os.SEEK_CUR) //Skip OptionalHeader