~ubuntu-branches/ubuntu/vivid/golang/vivid

« back to all changes in this revision

Viewing changes to src/pkg/debug/elf/file.go

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2013-08-20 14:06:23 UTC
  • mfrom: (14.1.23 saucy-proposed)
  • Revision ID: package-import@ubuntu.com-20130820140623-b414jfxi3m0qkmrq
Tags: 2:1.1.2-2ubuntu1
* Merge from Debian unstable (LP: #1211749, #1202027). Remaining changes:
  - 016-armhf-elf-header.patch: Use correct ELF header for armhf binaries.
  - d/control,control.cross: Update Breaks/Replaces for Ubuntu
    versions to ensure smooth upgrades, regenerate control file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
        ByteOrder  binary.ByteOrder
32
32
        Type       Type
33
33
        Machine    Machine
 
34
        Entry      uint64
34
35
}
35
36
 
36
37
// A File represents an open ELF file.
240
241
                }
241
242
                f.Type = Type(hdr.Type)
242
243
                f.Machine = Machine(hdr.Machine)
 
244
                f.Entry = uint64(hdr.Entry)
243
245
                if v := Version(hdr.Version); v != f.Version {
244
246
                        return nil, &FormatError{0, "mismatched ELF version", v}
245
247
                }
258
260
                }
259
261
                f.Type = Type(hdr.Type)
260
262
                f.Machine = Machine(hdr.Machine)
 
263
                f.Entry = uint64(hdr.Entry)
261
264
                if v := Version(hdr.Version); v != f.Version {
262
265
                        return nil, &FormatError{0, "mismatched ELF version", v}
263
266
                }
269
272
                shnum = int(hdr.Shnum)
270
273
                shstrndx = int(hdr.Shstrndx)
271
274
        }
272
 
        if shstrndx < 0 || shstrndx >= shnum {
 
275
 
 
276
        if shnum > 0 && shoff > 0 && (shstrndx < 0 || shstrndx >= shnum) {
273
277
                return nil, &FormatError{0, "invalid ELF shstrndx", shstrndx}
274
278
        }
275
279
 
364
368
                f.Sections[i] = s
365
369
        }
366
370
 
 
371
        if len(f.Sections) == 0 {
 
372
                return f, nil
 
373
        }
 
374
 
367
375
        // Load section header string table.
368
376
        shstrtab, err := f.Sections[shstrndx].Data()
369
377
        if err != nil {
416
424
 
417
425
        // The first entry is all zeros.
418
426
        var skip [Sym32Size]byte
419
 
        symtab.Read(skip[0:])
 
427
        symtab.Read(skip[:])
420
428
 
421
429
        symbols := make([]Symbol, symtab.Len()/Sym32Size)
422
430
 
459
467
 
460
468
        // The first entry is all zeros.
461
469
        var skip [Sym64Size]byte
462
 
        symtab.Read(skip[0:])
 
470
        symtab.Read(skip[:])
463
471
 
464
472
        symbols := make([]Symbol, symtab.Len()/Sym64Size)
465
473
 
533
541
                symNo := rela.Info >> 32
534
542
                t := R_X86_64(rela.Info & 0xffff)
535
543
 
536
 
                if symNo >= uint64(len(symbols)) {
 
544
                if symNo == 0 || symNo > uint64(len(symbols)) {
537
545
                        continue
538
546
                }
539
 
                sym := &symbols[symNo]
 
547
                sym := &symbols[symNo-1]
540
548
                if SymType(sym.Info&0xf) != STT_SECTION {
541
549
                        // We don't handle non-section relocations for now.
542
550
                        continue
597
605
}
598
606
 
599
607
// Symbols returns the symbol table for f.
 
608
//
 
609
// For compatibility with Go 1.0, Symbols omits the null symbol at index 0.
 
610
// After retrieving the symbols as symtab, an externally supplied index x
 
611
// corresponds to symtab[x-1], not symtab[x].
600
612
func (f *File) Symbols() ([]Symbol, error) {
601
613
        sym, _, err := f.getSymbols(SHT_SYMTAB)
602
614
        return sym, err
705
717
// gnuVersion adds Library and Version information to sym,
706
718
// which came from offset i of the symbol table.
707
719
func (f *File) gnuVersion(i int, sym *ImportedSymbol) {
708
 
        // Each entry is two bytes; skip undef entry at beginning.
 
720
        // Each entry is two bytes.
709
721
        i = (i + 1) * 2
710
722
        if i >= len(f.gnuVersym) {
711
723
                return
723
735
// referred to by the binary f that are expected to be
724
736
// linked with the binary at dynamic link time.
725
737
func (f *File) ImportedLibraries() ([]string, error) {
 
738
        return f.DynString(DT_NEEDED)
 
739
}
 
740
 
 
741
// DynString returns the strings listed for the given tag in the file's dynamic
 
742
// section.
 
743
//
 
744
// The tag must be one that takes string values: DT_NEEDED, DT_SONAME, DT_RPATH, or
 
745
// DT_RUNPATH.
 
746
func (f *File) DynString(tag DynTag) ([]string, error) {
 
747
        switch tag {
 
748
        case DT_NEEDED, DT_SONAME, DT_RPATH, DT_RUNPATH:
 
749
        default:
 
750
                return nil, fmt.Errorf("non-string-valued tag %v", tag)
 
751
        }
726
752
        ds := f.SectionByType(SHT_DYNAMIC)
727
753
        if ds == nil {
728
754
                // not dynamic, so no libraries
738
764
        }
739
765
        var all []string
740
766
        for len(d) > 0 {
741
 
                var tag DynTag
742
 
                var value uint64
 
767
                var t DynTag
 
768
                var v uint64
743
769
                switch f.Class {
744
770
                case ELFCLASS32:
745
 
                        tag = DynTag(f.ByteOrder.Uint32(d[0:4]))
746
 
                        value = uint64(f.ByteOrder.Uint32(d[4:8]))
 
771
                        t = DynTag(f.ByteOrder.Uint32(d[0:4]))
 
772
                        v = uint64(f.ByteOrder.Uint32(d[4:8]))
747
773
                        d = d[8:]
748
774
                case ELFCLASS64:
749
 
                        tag = DynTag(f.ByteOrder.Uint64(d[0:8]))
750
 
                        value = f.ByteOrder.Uint64(d[8:16])
 
775
                        t = DynTag(f.ByteOrder.Uint64(d[0:8]))
 
776
                        v = f.ByteOrder.Uint64(d[8:16])
751
777
                        d = d[16:]
752
778
                }
753
 
                if tag == DT_NEEDED {
754
 
                        s, ok := getString(str, int(value))
 
779
                if t == tag {
 
780
                        s, ok := getString(str, int(v))
755
781
                        if ok {
756
782
                                all = append(all, s)
757
783
                        }
758
784
                }
759
785
        }
760
 
 
761
786
        return all, nil
762
787
}