@@ -16,14 +16,23 @@ import (
16
16
"github.com/wader/fq/pkg/scalar"
17
17
)
18
18
19
+ var x86_64Group decode.Group
20
+ var arm64Group decode.Group
21
+
19
22
func init () {
20
23
interp .RegisterFormat (
21
24
format .Elf ,
22
25
& decode.Format {
23
26
Description : "Executable and Linkable Format" ,
24
27
Groups : []* decode.Group {format .Probe },
25
28
DecodeFn : elfDecode ,
26
- })
29
+ Dependencies : []decode.Dependency {
30
+ // TODO: x86 32/16?
31
+ {Groups : []* decode.Group {format .X86_64 }, Out : & x86_64Group },
32
+ {Groups : []* decode.Group {format .Arm64 }, Out : & arm64Group },
33
+ },
34
+ },
35
+ )
27
36
}
28
37
29
38
const (
@@ -167,6 +176,15 @@ var phTypeNames = scalar.UintRangeToScalar{
167
176
{Range : [2 ]uint64 {0x70000000 , 0x7fffffff }, S : scalar.Uint {Sym : "proc" , Description : "Processor-specific" }},
168
177
}
169
178
179
+ var machineToFormatFn = map [int ]func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )){
180
+ EM_X86_64 : func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )) {
181
+ d .Format (& x86_64Group , format.X86_64In {Base : int64 (base ), SymLookup : symLookup })
182
+ },
183
+ EM_ARM64 : func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )) {
184
+ d .Format (& arm64Group , format.ARM64In {Base : int64 (base ), SymLookup : symLookup })
185
+ },
186
+ }
187
+
170
188
const (
171
189
NT_PRSTATUS = 1
172
190
NT_PRFPREG = 2
@@ -980,6 +998,8 @@ func elfDecodeDynamicTags(d *decode.D, ec elfContext, dc dynamicContext) {
980
998
}
981
999
982
1000
func elfDecodeSectionHeader (d * decode.D , ec elfContext , sh sectionHeader ) {
1001
+ var execInstr bool
1002
+
983
1003
shFlags := func (d * decode.D , archBits int ) {
984
1004
d .FieldStruct ("flags" , func (d * decode.D ) {
985
1005
if d .Endian == decode .LittleEndian {
@@ -988,7 +1008,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
988
1008
d .FieldBool ("strings" )
989
1009
d .FieldBool ("merge" )
990
1010
d .FieldU1 ("unused0" )
991
- d .FieldBool ("execinstr" )
1011
+ execInstr = d .FieldBool ("execinstr" )
992
1012
d .FieldBool ("alloc" )
993
1013
d .FieldBool ("write" )
994
1014
d .FieldBool ("tls" )
@@ -1018,13 +1038,14 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
1018
1038
d .FieldBool ("strings" )
1019
1039
d .FieldBool ("merge" )
1020
1040
d .FieldU1 ("unused2" )
1021
- d .FieldBool ("execinstr" )
1041
+ execInstr = d .FieldBool ("execinstr" )
1022
1042
d .FieldBool ("alloc" )
1023
1043
d .FieldBool ("write" )
1024
1044
}
1025
1045
})
1026
1046
}
1027
1047
1048
+ var addr uint64
1028
1049
var offset int64
1029
1050
var size int64
1030
1051
var entSize int64
@@ -1035,7 +1056,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
1035
1056
d .FieldU32 ("name" , strTable (ec .strTabMap [STRTAB_SHSTRTAB ]))
1036
1057
typ = d .FieldU32 ("type" , sectionHeaderTypeMap , scalar .UintHex )
1037
1058
shFlags (d , ec .archBits )
1038
- d .FieldU ("addr" , ec .archBits , scalar .UintHex )
1059
+ addr = d .FieldU ("addr" , ec .archBits , scalar .UintHex )
1039
1060
offset = int64 (d .FieldU ("offset" , ec .archBits )) * 8
1040
1061
size = int64 (d .FieldU32 ("size" , scalar .UintHex ) * 8 )
1041
1062
d .FieldU32 ("link" )
@@ -1046,7 +1067,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
1046
1067
d .FieldU32 ("name" , strTable (ec .strTabMap [STRTAB_SHSTRTAB ]))
1047
1068
typ = d .FieldU32 ("type" , sectionHeaderTypeMap , scalar .UintHex )
1048
1069
shFlags (d , ec .archBits )
1049
- d .FieldU ("addr" , ec .archBits , scalar .UintHex )
1070
+ addr = d .FieldU ("addr" , ec .archBits , scalar .UintHex )
1050
1071
offset = int64 (d .FieldU ("offset" , ec .archBits , scalar .UintHex ) * 8 )
1051
1072
size = int64 (d .FieldU64 ("size" ) * 8 )
1052
1073
d .FieldU32 ("link" )
@@ -1079,9 +1100,34 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
1079
1100
elfDecodeSymbolTable (d , ec , int (size / entSize ), ec .strTabMap [STRTAB_DYNSTR ])
1080
1101
})
1081
1102
case SHT_PROGBITS :
1082
- // TODO: name progbits?
1083
- // TODO: decode opcodes
1084
- d .FieldRawLen ("data" , size )
1103
+ // TODO: verify this, seems to result in strange relative addresses
1104
+ symLookup := func (symAddr uint64 ) (string , uint64 ) {
1105
+ var best * symbol
1106
+
1107
+ for _ , sh := range ec .sections {
1108
+ for i , s := range sh .symbols {
1109
+ if symAddr >= s .value && (best == nil || symAddr - s .value < best .value - s .value ) {
1110
+ best = & sh .symbols [i ]
1111
+ }
1112
+ }
1113
+ }
1114
+ if best == nil {
1115
+ return "" , 0
1116
+ }
1117
+ return strIndexNull (int (best .name ), ec .strTabMap [STRTAB_STRTAB ]), best .value
1118
+ }
1119
+
1120
+ // TODO: name progbits? instructions?
1121
+ if fn , ok := machineToFormatFn [ec .machine ]; execInstr && ok {
1122
+ d .FieldArray ("code" , func (d * decode.D ) {
1123
+ d .FramedFn (size , func (d * decode.D ) {
1124
+ fn (d , addr , symLookup )
1125
+ })
1126
+ })
1127
+ } else {
1128
+ d .FieldRawLen ("data" , size )
1129
+ }
1130
+
1085
1131
case SHT_GNU_HASH :
1086
1132
d .FieldStruct ("gnu_hash" , func (d * decode.D ) {
1087
1133
elfDecodeGNUHash (d , ec , size , ec .strTabMap [STRTAB_DYNSTR ])
0 commit comments