OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package pe implements access to PE (Microsoft Windows Portable Executable) fi
les. | 5 // Package pe implements access to PE (Microsoft Windows Portable Executable) fi
les. |
6 package pe | 6 package pe |
7 | 7 |
8 import ( | 8 import ( |
9 "debug/dwarf" | 9 "debug/dwarf" |
10 "encoding/binary" | 10 "encoding/binary" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 // Embed ReaderAt for ReadAt method. | 42 // Embed ReaderAt for ReadAt method. |
43 // Do not embed SectionReader directly | 43 // Do not embed SectionReader directly |
44 // to avoid having Read and Seek. | 44 // to avoid having Read and Seek. |
45 // If a client wants Read and Seek it must use | 45 // If a client wants Read and Seek it must use |
46 // Open() to avoid fighting over the seek offset | 46 // Open() to avoid fighting over the seek offset |
47 // with other clients. | 47 // with other clients. |
48 io.ReaderAt | 48 io.ReaderAt |
49 sr *io.SectionReader | 49 sr *io.SectionReader |
50 } | 50 } |
51 | 51 |
| 52 type ImportDirectory struct { |
| 53 OriginalFirstThunk uint32 |
| 54 TimeDateStamp uint32 |
| 55 ForwarderChain uint32 |
| 56 Name uint32 |
| 57 FirstThunk uint32 |
| 58 |
| 59 dll string |
| 60 rva []uint32 |
| 61 } |
| 62 |
52 // Data reads and returns the contents of the PE section. | 63 // Data reads and returns the contents of the PE section. |
53 func (s *Section) Data() ([]byte, os.Error) { | 64 func (s *Section) Data() ([]byte, os.Error) { |
54 dat := make([]byte, s.sr.Size()) | 65 dat := make([]byte, s.sr.Size()) |
55 n, err := s.sr.ReadAt(dat, 0) | 66 n, err := s.sr.ReadAt(dat, 0) |
56 return dat[0:n], err | 67 return dat[0:n], err |
57 } | 68 } |
58 | 69 |
59 // Open returns a new ReadSeeker reading the PE section. | 70 // Open returns a new ReadSeeker reading the PE section. |
60 func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<
63-1) } | 71 func (s *Section) Open() io.ReadSeeker { return io.NewSectionReader(s.sr, 0, 1<<
63-1) } |
61 | 72 |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 b, err := s.Data() | 233 b, err := s.Data() |
223 if err != nil && uint32(len(b)) < s.Size { | 234 if err != nil && uint32(len(b)) < s.Size { |
224 return nil, err | 235 return nil, err |
225 } | 236 } |
226 dat[i] = b | 237 dat[i] = b |
227 } | 238 } |
228 | 239 |
229 abbrev, info, str := dat[0], dat[1], dat[2] | 240 abbrev, info, str := dat[0], dat[1], dat[2] |
230 return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) | 241 return dwarf.New(abbrev, nil, nil, info, nil, nil, nil, str) |
231 } | 242 } |
| 243 |
| 244 // ImportedSymbols returns the names of all symbols |
| 245 // referred to by the binary f that are expected to be |
| 246 // satisfied by other libraries at dynamic load time. |
| 247 // It does not return weak symbols. |
| 248 func (f *File) ImportedSymbols() ([]string, os.Error) { |
| 249 ds := f.Section(".idata") |
| 250 if ds == nil { |
| 251 // not dynamic, so no libraries |
| 252 return nil, nil |
| 253 } |
| 254 d, err := ds.Data() |
| 255 if err != nil { |
| 256 return nil, err |
| 257 } |
| 258 var ida []ImportDirectory |
| 259 for len(d) > 0 { |
| 260 var dt ImportDirectory |
| 261 dt.OriginalFirstThunk = binary.LittleEndian.Uint32(d[0:4]) |
| 262 dt.Name = binary.LittleEndian.Uint32(d[12:16]) |
| 263 dt.FirstThunk = binary.LittleEndian.Uint32(d[16:20]) |
| 264 d = d[20:] |
| 265 if dt.OriginalFirstThunk == 0 { |
| 266 break |
| 267 } |
| 268 ida = append(ida, dt) |
| 269 } |
| 270 for i, _ := range ida { |
| 271 for len(d) > 0 { |
| 272 va := binary.LittleEndian.Uint32(d[0:4]) |
| 273 d = d[4:] |
| 274 if va == 0 { |
| 275 break |
| 276 } |
| 277 ida[i].rva = append(ida[i].rva, va) |
| 278 } |
| 279 } |
| 280 for _, _ = range ida { |
| 281 for len(d) > 0 { |
| 282 va := binary.LittleEndian.Uint32(d[0:4]) |
| 283 d = d[4:] |
| 284 if va == 0 { |
| 285 break |
| 286 } |
| 287 } |
| 288 } |
| 289 names, _ := ds.Data() |
| 290 var all []string |
| 291 for _, dt := range ida { |
| 292 dt.dll, _ = getString(names, int(dt.Name-ds.VirtualAddress)) |
| 293 for _, va := range dt.rva { |
| 294 fn, _ := getString(names, int(va-ds.VirtualAddress+2)) |
| 295 all = append(all, fn+":"+dt.dll) |
| 296 } |
| 297 } |
| 298 |
| 299 return all, nil |
| 300 } |
| 301 |
| 302 // ImportedLibraries returns the names of all libraries |
| 303 // referred to by the binary f that are expected to be |
| 304 // linked with the binary at dynamic link time. |
| 305 func (f *File) ImportedLibraries() ([]string, os.Error) { |
| 306 // TODO |
| 307 // cgo -dynimport don't use this for windows PE, so just return. |
| 308 return nil, nil |
| 309 } |
OLD | NEW |