gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

elf.go (2092B)


      1 package internal
      2 
      3 import (
      4 	"debug/elf"
      5 	"fmt"
      6 	"io"
      7 )
      8 
      9 type SafeELFFile struct {
     10 	*elf.File
     11 }
     12 
     13 // NewSafeELFFile reads an ELF safely.
     14 //
     15 // Any panic during parsing is turned into an error. This is necessary since
     16 // there are a bunch of unfixed bugs in debug/elf.
     17 //
     18 // https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+debug%2Felf+in%3Atitle
     19 func NewSafeELFFile(r io.ReaderAt) (safe *SafeELFFile, err error) {
     20 	defer func() {
     21 		r := recover()
     22 		if r == nil {
     23 			return
     24 		}
     25 
     26 		safe = nil
     27 		err = fmt.Errorf("reading ELF file panicked: %s", r)
     28 	}()
     29 
     30 	file, err := elf.NewFile(r)
     31 	if err != nil {
     32 		return nil, err
     33 	}
     34 
     35 	return &SafeELFFile{file}, nil
     36 }
     37 
     38 // OpenSafeELFFile reads an ELF from a file.
     39 //
     40 // It works like NewSafeELFFile, with the exception that safe.Close will
     41 // close the underlying file.
     42 func OpenSafeELFFile(path string) (safe *SafeELFFile, err error) {
     43 	defer func() {
     44 		r := recover()
     45 		if r == nil {
     46 			return
     47 		}
     48 
     49 		safe = nil
     50 		err = fmt.Errorf("reading ELF file panicked: %s", r)
     51 	}()
     52 
     53 	file, err := elf.Open(path)
     54 	if err != nil {
     55 		return nil, err
     56 	}
     57 
     58 	return &SafeELFFile{file}, nil
     59 }
     60 
     61 // Symbols is the safe version of elf.File.Symbols.
     62 func (se *SafeELFFile) Symbols() (syms []elf.Symbol, err error) {
     63 	defer func() {
     64 		r := recover()
     65 		if r == nil {
     66 			return
     67 		}
     68 
     69 		syms = nil
     70 		err = fmt.Errorf("reading ELF symbols panicked: %s", r)
     71 	}()
     72 
     73 	syms, err = se.File.Symbols()
     74 	return
     75 }
     76 
     77 // DynamicSymbols is the safe version of elf.File.DynamicSymbols.
     78 func (se *SafeELFFile) DynamicSymbols() (syms []elf.Symbol, err error) {
     79 	defer func() {
     80 		r := recover()
     81 		if r == nil {
     82 			return
     83 		}
     84 
     85 		syms = nil
     86 		err = fmt.Errorf("reading ELF dynamic symbols panicked: %s", r)
     87 	}()
     88 
     89 	syms, err = se.File.DynamicSymbols()
     90 	return
     91 }
     92 
     93 // SectionsByType returns all sections in the file with the specified section type.
     94 func (se *SafeELFFile) SectionsByType(typ elf.SectionType) []*elf.Section {
     95 	sections := make([]*elf.Section, 0, 1)
     96 	for _, section := range se.Sections {
     97 		if section.Type == typ {
     98 			sections = append(sections, section)
     99 		}
    100 	}
    101 	return sections
    102 }