@@ -9,32 +9,43 @@ import (
99 "fmt"
1010 "stackplz/pkg/util"
1111 "stackplz/user/config"
12+ "strings"
13+ "sync"
1214)
1315
1416type LibInfo struct {
15- Pid uint32
1617 BaseAddr uint64
1718 LibSize uint64
19+ EndAddr uint64
1820 LibPath string
1921}
2022
2123type MapsHelper map [uint32 ]PidMaps
2224type PidMaps map [string ][]LibInfo
2325
24- func NewMapsHelper () * MapsHelper {
25- helper := & MapsHelper {}
26+ func NewMapsHelper () MapsHelper {
27+ helper := make ( MapsHelper )
2628 return helper
2729}
2830
2931func (this * MapsHelper ) UpdateMaps (soinfo * SoInfoEvent ) {
32+ // 拙劣的函数
33+ maps_lock .Lock ()
34+ defer maps_lock .Unlock ()
3035 pid_maps , ok := (* this )[soinfo .Pid ]
3136 if ! ok {
32- (* this )[soinfo .Pid ] = PidMaps {}
37+ pid_maps = make (PidMaps )
38+ (* this )[soinfo .Pid ] = pid_maps
39+ }
40+ pid_maps = (* this )[soinfo .Pid ]
41+ if soinfo .LibPath == "" {
42+ soinfo .LibPath = fmt .Sprintf ("UNNAMED_0x%x" , soinfo .BaseAddr )
3343 }
3444 info := LibInfo {
3545 LibSize : soinfo .LibSize ,
3646 BaseAddr : soinfo .BaseAddr ,
3747 LibPath : soinfo .LibPath ,
48+ EndAddr : soinfo .BaseAddr + soinfo .LibSize ,
3849 }
3950 base_list , ok := pid_maps [soinfo .LibPath ]
4051 if ok {
@@ -48,24 +59,59 @@ func (this *MapsHelper) UpdateMaps(soinfo *SoInfoEvent) {
4859 }
4960 if ! has_find {
5061 base_list = append (base_list , info )
62+ pid_maps [soinfo .LibPath ] = base_list
5163 }
5264 } else {
5365 pid_maps [soinfo .LibPath ] = []LibInfo {info }
5466 }
67+ (* this )[soinfo .Pid ] = pid_maps
5568}
5669
57- func (this * MapsHelper ) GetOffset (addr uint64 ) (info string ) {
58- return ""
70+ func (this * MapsHelper ) GetOffset (pid uint32 , addr uint64 ) (info string ) {
71+ maps_lock .Lock ()
72+ defer maps_lock .Unlock ()
73+ pid_maps , ok := (* this )[pid ]
74+ if ! ok {
75+ // 暂时没有这个 pid 对应的 maps 信息
76+ return fmt .Sprintf ("UNNKOWN + 0x%x" , addr )
77+ }
78+ // 这里的计算是以库的每个段都是前后连续为前提的,暂时就这样
79+ // 但是实际上确实存在一些奇怪的操作
80+ // 1. 不连续的段
81+ // 2. 两个或者多个同名/同路径的库存在于maps中
82+ // 3. 其他...
83+ // 全部遍历是一种低效的写法,但是暂时没有更好的想法,就这样
84+ // 一定要优化那么应该在每次 pid_maps 变更的时候就进行排序 并按照基址大小插入
85+ var off_list []string = []string {}
86+ for lib_path , lib_infos := range pid_maps {
87+ for _ , lib_info := range lib_infos {
88+ if addr >= lib_info .BaseAddr && addr < lib_info .EndAddr {
89+ offset := fmt .Sprintf ("%s + 0x%x" , lib_path , addr - lib_info .BaseAddr )
90+ off_list = append (off_list , offset )
91+ }
92+ }
93+ }
94+ if len (off_list ) == 0 {
95+ return fmt .Sprintf ("NOTFOUND + 0x%x" , addr )
96+ }
97+ return strings .Join (off_list [:], "," )
5998}
6099
100+ // func (this *MapsHelper) toString() (s string) {
101+ // s = ""
102+ // s += fmt.Sprintln(*this)
103+ // return s
104+ // }
105+
61106var maps_helper = NewMapsHelper ()
107+ var maps_lock sync.Mutex
62108
63109type SoInfoEvent struct {
64110 event_type EventType
65111 KEvent
66- mconf * config.ModuleConfig
67- Pid uint32
68- Tid uint32
112+ mconf * config.ModuleConfig
113+ // Pid uint32
114+ // Tid uint32
69115 Comm [16 ]byte
70116 BaseAddr uint64
71117 LibSize uint64
@@ -96,7 +142,7 @@ func (this *SoInfoEvent) Decode() (err error) {
96142 return
97143 }
98144 this .LibPath = util .B2STrim (this .RealPath [:])
99-
145+ maps_helper . UpdateMaps ( this )
100146 return nil
101147}
102148
0 commit comments