Open satisfies the plugin.ObjTool interface.
(name string, start, limit, offset uint64, relocationSymbol string)
| 285 | |
| 286 | // Open satisfies the plugin.ObjTool interface. |
| 287 | func (bu *Binutils) Open(name string, start, limit, offset uint64, relocationSymbol string) (plugin.ObjFile, error) { |
| 288 | b := bu.get() |
| 289 | |
| 290 | // Make sure file is a supported executable. |
| 291 | // This uses magic numbers, mainly to provide better error messages but |
| 292 | // it should also help speed. |
| 293 | |
| 294 | if _, err := os.Stat(name); err != nil { |
| 295 | // For testing, do not require file name to exist. |
| 296 | if strings.Contains(b.addr2line, "testdata/") { |
| 297 | return &fileAddr2Line{file: file{b: b, name: name}}, nil |
| 298 | } |
| 299 | return nil, err |
| 300 | } |
| 301 | |
| 302 | // Read the first 4 bytes of the file. |
| 303 | |
| 304 | f, err := os.Open(name) |
| 305 | if err != nil { |
| 306 | return nil, fmt.Errorf("error opening %s: %v", name, err) |
| 307 | } |
| 308 | defer f.Close() |
| 309 | |
| 310 | var header [4]byte |
| 311 | if _, err = io.ReadFull(f, header[:]); err != nil { |
| 312 | return nil, fmt.Errorf("error reading magic number from %s: %v", name, err) |
| 313 | } |
| 314 | |
| 315 | elfMagic := string(header[:]) |
| 316 | |
| 317 | // Match against supported file types. |
| 318 | if elfMagic == elf.ELFMAG { |
| 319 | f, err := b.openELF(name, start, limit, offset, relocationSymbol) |
| 320 | if err != nil { |
| 321 | return nil, fmt.Errorf("error reading ELF file %s: %v", name, err) |
| 322 | } |
| 323 | return f, nil |
| 324 | } |
| 325 | |
| 326 | // Mach-O magic numbers can be big or little endian. |
| 327 | machoMagicLittle := binary.LittleEndian.Uint32(header[:]) |
| 328 | machoMagicBig := binary.BigEndian.Uint32(header[:]) |
| 329 | |
| 330 | if machoMagicLittle == macho.Magic32 || machoMagicLittle == macho.Magic64 || |
| 331 | machoMagicBig == macho.Magic32 || machoMagicBig == macho.Magic64 { |
| 332 | f, err := b.openMachO(name, start, limit, offset) |
| 333 | if err != nil { |
| 334 | return nil, fmt.Errorf("error reading Mach-O file %s: %v", name, err) |
| 335 | } |
| 336 | return f, nil |
| 337 | } |
| 338 | if machoMagicLittle == macho.MagicFat || machoMagicBig == macho.MagicFat { |
| 339 | f, err := b.openFatMachO(name, start, limit, offset) |
| 340 | if err != nil { |
| 341 | return nil, fmt.Errorf("error reading fat Mach-O file %s: %v", name, err) |
| 342 | } |
| 343 | return f, nil |
| 344 | } |