github.com/ks888/tgo@v0.0.0-20190130135156-80bf89407292/tracee/binary_linux.go (about) 1 package tracee 2 3 import ( 4 "bytes" 5 "compress/zlib" 6 "debug/dwarf" 7 "debug/elf" 8 "encoding/binary" 9 "io" 10 ) 11 12 var locationListSectionNames = []string{ 13 ".zdebug_loc", 14 ".debug_loc", 15 } 16 17 func openBinaryFile(pathToProgram string, goVersion GoVersion) (BinaryFile, error) { 18 elfFile, err := elf.Open(pathToProgram) 19 if err != nil { 20 return nil, err 21 } 22 var closer io.Closer = elfFile 23 24 data, locList, err := findDWARF(elfFile) 25 if err != nil { 26 binaryFile, err := newNonDebuggableBinaryFile(closer) 27 if err != nil { 28 closer.Close() 29 } 30 return binaryFile, err 31 } 32 33 binaryFile, err := newDebuggableBinaryFile(dwarfData{Data: data, locationList: locList}, goVersion, closer) 34 if err != nil { 35 closer.Close() 36 } 37 return binaryFile, err 38 } 39 40 func findDWARF(elfFile *elf.File) (data *dwarf.Data, locList []byte, err error) { 41 var locListSection *elf.Section 42 for _, locListSectionName := range locationListSectionNames { 43 locListSection = elfFile.Section(locListSectionName) 44 if locListSection != nil { 45 break 46 } 47 } 48 // older go version doesn't create a location list section. 49 50 locList, err = buildLocationListData(locListSection) 51 if err != nil { 52 return nil, nil, err 53 } 54 55 data, err = elfFile.DWARF() 56 return data, locList, err 57 } 58 59 func buildLocationListData(locListSection *elf.Section) ([]byte, error) { 60 if locListSection == nil { 61 return nil, nil 62 } 63 64 rawData, err := locListSection.Data() 65 if err != nil { 66 return nil, err 67 } 68 69 if string(rawData[:4]) != "ZLIB" || len(rawData) < 12 { 70 return rawData, nil 71 } 72 73 dlen := binary.BigEndian.Uint64(rawData[4:12]) 74 uncompressedData := make([]byte, dlen) 75 76 r, err := zlib.NewReader(bytes.NewBuffer(rawData[12:])) 77 if err != nil { 78 return nil, err 79 } 80 defer r.Close() 81 82 _, err = io.ReadFull(r, uncompressedData) 83 return uncompressedData, err 84 }