@@ -16,12 +16,20 @@ import (
1616 "github.com/wader/fq/pkg/scalar"
1717)
1818
19+ var x86_64Format decode.Group
20+ var arm64Format decode.Group
21+
1922func init () {
2023 registry .MustRegister (decode.Format {
2124 Name : format .ELF ,
2225 Description : "Executable and Linkable Format" ,
2326 Groups : []string {format .PROBE },
2427 DecodeFn : elfDecode ,
28+ Dependencies : []decode.Dependency {
29+ // TODO: x86_32?
30+ {Names : []string {format .X86_64 }, Group : & x86_64Format },
31+ {Names : []string {format .ARM64 }, Group : & arm64Format },
32+ },
2533 })
2634}
2735
@@ -131,6 +139,15 @@ var machineNames = scalar.UToScalar{
131139 0x101 : {Sym : "wdc_65C816" , Description : "WDC 65C816" },
132140}
133141
142+ var machineToFormatFn = map [int ]func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )){
143+ EM_X86_64 : func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )) {
144+ d .Format (x86_64Format , format.X86_64In {Base : int64 (base ), SymLookup : symLookup })
145+ },
146+ EM_ARM64 : func (d * decode.D , base uint64 , symLookup func (uint64 ) (string , uint64 )) {
147+ d .Format (arm64Format , format.ARM64In {Base : int64 (base ), SymLookup : symLookup })
148+ },
149+ }
150+
134151var phTypeNames = scalar.URangeToScalar {
135152 {Range : [2 ]uint64 {0x00000000 , 0x00000000 }, S : scalar.S {Sym : "null" , Description : "Unused element" }},
136153 {Range : [2 ]uint64 {0x00000001 , 0x00000001 }, S : scalar.S {Sym : "load" , Description : "Loadable segment" }},
@@ -767,6 +784,8 @@ func elfDecodeDynamicTags(d *decode.D, ec elfContext, dc dynamicContext) {
767784}
768785
769786func elfDecodeSectionHeader (d * decode.D , ec elfContext , sh sectionHeader ) {
787+ var execInstr bool
788+
770789 shFlags := func (d * decode.D , archBits int ) {
771790 d .FieldStruct ("flags" , func (d * decode.D ) {
772791 if d .Endian == decode .LittleEndian {
@@ -775,7 +794,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
775794 d .FieldBool ("strings" )
776795 d .FieldBool ("merge" )
777796 d .FieldU1 ("unused0" )
778- d .FieldBool ("execinstr" )
797+ execInstr = d .FieldBool ("execinstr" )
779798 d .FieldBool ("alloc" )
780799 d .FieldBool ("write" )
781800 d .FieldBool ("tls" )
@@ -805,13 +824,14 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
805824 d .FieldBool ("strings" )
806825 d .FieldBool ("merge" )
807826 d .FieldU1 ("unused2" )
808- d .FieldBool ("execinstr" )
827+ execInstr = d .FieldBool ("execinstr" )
809828 d .FieldBool ("alloc" )
810829 d .FieldBool ("write" )
811830 }
812831 })
813832 }
814833
834+ var addr uint64
815835 var offset int64
816836 var size int64
817837 var entSize int64
@@ -822,7 +842,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
822842 d .FieldU32 ("name" , strTable (ec .strTabMap [STRTAB_SHSTRTAB ]))
823843 typ = d .FieldU32 ("type" , sectionHeaderTypeMap , scalar .Hex )
824844 shFlags (d , ec .archBits )
825- d .FieldU ("addr" , ec .archBits , scalar .Hex )
845+ addr = d .FieldU ("addr" , ec .archBits , scalar .Hex )
826846 offset = int64 (d .FieldU ("offset" , ec .archBits )) * 8
827847 size = int64 (d .FieldU32 ("size" , scalar .Hex ) * 8 )
828848 d .FieldU32 ("link" )
@@ -833,7 +853,7 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
833853 d .FieldU32 ("name" , strTable (ec .strTabMap [STRTAB_SHSTRTAB ]))
834854 typ = d .FieldU32 ("type" , sectionHeaderTypeMap , scalar .Hex )
835855 shFlags (d , ec .archBits )
836- d .FieldU ("addr" , ec .archBits , scalar .Hex )
856+ addr = d .FieldU ("addr" , ec .archBits , scalar .Hex )
837857 offset = int64 (d .FieldU ("offset" , ec .archBits , scalar .Hex ) * 8 )
838858 size = int64 (d .FieldU64 ("size" ) * 8 )
839859 d .FieldU32 ("link" )
@@ -866,9 +886,34 @@ func elfDecodeSectionHeader(d *decode.D, ec elfContext, sh sectionHeader) {
866886 elfDecodeSymbolTable (d , ec , int (size / entSize ), ec .strTabMap [STRTAB_DYNSTR ])
867887 })
868888 case SHT_PROGBITS :
869- // TODO: name progbits?
870- // TODO: decode opcodes
871- d .FieldRawLen ("data" , size )
889+ // TODO: verify this, seems to result in strange relative addresses
890+ symLookup := func (symAddr uint64 ) (string , uint64 ) {
891+ var best * symbol
892+
893+ for _ , sh := range ec .sections {
894+ for i , s := range sh .symbols {
895+ if symAddr >= s .value && (best == nil || symAddr - s .value < best .value - s .value ) {
896+ best = & sh .symbols [i ]
897+ }
898+ }
899+ }
900+ if best == nil {
901+ return "" , 0
902+ }
903+ return strIndexNull (int (best .name ), ec .strTabMap [STRTAB_STRTAB ]), best .value
904+ }
905+
906+ // TODO: name progbits? instructions?
907+ if fn , ok := machineToFormatFn [ec .machine ]; execInstr && ok {
908+ d .FieldArray ("code" , func (d * decode.D ) {
909+ d .FramedFn (size , func (d * decode.D ) {
910+ fn (d , addr , symLookup )
911+ })
912+ })
913+ } else {
914+ d .FieldRawLen ("data" , size )
915+ }
916+
872917 case SHT_GNU_HASH :
873918 d .FieldStruct ("gnu_hash" , func (d * decode.D ) {
874919 elfDecodeGNUHash (d , ec , size , ec .strTabMap [STRTAB_DYNSTR ])
0 commit comments