aboutsummaryrefslogtreecommitdiff
path: root/elymas/memdump.ey
blob: 65557f85751aca969e0963b998df469f7e7ca2e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
txt .consume .|hu "%" deffd

%400000000000 ==:MARKBASE
%500000000000 ==:BLOCKBASE
%600000000000 ==:HEAPBASE
%100000000000 ==:ELFBASE

<
  sys .asm .ops ":" via
  sys .asm "::" via

  [ # ==addr
    8 /r15 :subqImm8Reg
    /r15 :popqMem

    /rax :popqReg
    8 /rax /rax :movqMemDisp8Reg # this should be a boxed integer
    /rax :pushqMem # load data to stack
    ::internalAllocateInteger /rax :movqImmReg
    /rax :callqReg
    8 /rax :popqMemDisp8 # store data to integer object
    /rax :pushqReg

    /r15 :pushqMem
    8 /r15 :addqImm8Reg
    :retn
  ] [ ] sys .asm .createFunction
> -- /peek64 deffd

sys .linux "+" via

<
  "shared\0" +ORDONLY 0 +open ==fd
  fd +fstat -- # TODO: handle errors
            .size ==s
  ELFBASE s +PROTREAD +MAPPRIVATE fd 0 +mmap ELFBASE eq assert
> --

ELFBASE 32 add peek64 _ dump ==phdr
ELFBASE 56 add peek64 65536 mod _ dump ==phdrCount

[
  phdrCount {
    ELFBASE phdr add peek64 %100000000 mod 1 eq { # LOAD program header
      <
        ELFBASE phdr add 8 add peek64 ==fileStart
        ELFBASE phdr add 16 add peek64 ==memoryStart
        ELFBASE phdr add 32 add peek64 memoryStart add ==memoryEnd
      >
    } rep
    phdr %38 add =phdr
  } rep
] _ ==memoryLayout

{ =*f _ =*a len ==maxI 0 ==i
  {
    i maxI lt { i a f } { 0 } ? *
  } { i 1 add =i } loop
} /eachWhile deffd

{ ==addr
  memoryLayout { ==m
    [
      { addr m .memoryStart lt } { 1 }
      { addr m .memoryEnd ge } { 1 }
      { 1 } {
        addr m .memoryStart sub m .fileStart add ELFBASE add peek64
        0 # loop done
      }
    ] conds
  } eachWhile
} /peekElf64 deffst

HEAPBASE peekElf64 %FFFFFFFFFFFF0000 band %9E00000000000000 eq assert

sys .asm .|programStart sys .asm .rawCodeAddress { add peekElf64 }_ =*peekProgramStart
2 peekProgramStart _ dump ==initialRsp
12 peekProgramStart _ dump ==initialR15
32 peekProgramStart HEAPBASE add _ dump ==HEAPEND
78 peekProgramStart _ dump ==initialR14

<
  HEAPEND HEAPBASE sub 16 div 8 div str .alloc _ str .zero ==objectSeen
  {
    HEAPBASE sub 16 div _ objectSeen str .bitTest -01
                          objectSeen str .bitSet
  }
> -- /seen deffst


1 neg ==indent
{ ==addr ==header
  indent { " " sys .out .writeall } rep
  header sys .out .writeall
  " " sys .out .writeall
  addr txt .produce .hu sys .out .writeall
  "\n" sys .out .writeall
} /out deffst

{ ==addr ==header ==type
  indent { " " sys .out .writeall } rep
  header sys .out .writeall
  " " sys .out .writeall
  addr txt .produce .hu sys .out .writeall
  " " sys .out .writeall
  type sys .out .writeall
  "\n" sys .out .writeall
} /out2 deffst

{ ==addr
  indent 1 add =indent
  [
    { addr HEAPBASE lt } { "--<low>---" addr out }
    { addr HEAPEND ge } { "--<high>--" addr out }
    { addr seen } { "--<seen>--" addr out }
    { 1 } {
      { "----------" addr out2 } ":" deffst
      addr peekElf64 %1000000000000000 div
      [
        { :integer }
        { :string
          addr 16 add peekElf64 "len:" -01 out
          addr 24 add peekElf64 256 math .base str .fromArray 0 out
        }
        { :errornous_2 }
        { :errornous_3 }
        { :extension_area
          addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range {
            8 mul addr add peekElf64 dumpElf
          } each
        }
        { :function
          addr 8 add peekElf64 dumpElf 
          addr 16 add peekElf64 dumpElf 
          addr 24 add peekElf64 dumpElf 
        }
        { :function_code
          addr 16 add peekElf64 %FFFF band %B848 eq
          addr 26 add peekElf64 %FFFF band %E0FF eq and
          {
            addr 18 add peekElf64 16 sub dumpElf
          } {
            addr 8 add peekElf64 _ "oplen:" -01 out ==oplen
            addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 2 oplen 8 div add -01 range {
              8 mul addr add peekElf64 dumpElf
            } each
          } ? *
        }
        { :array
          addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range {
            8 mul addr add peekElf64 dumpElf
          } each
        }
        { :function_type
          addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range {
            8 mul addr add peekElf64 dumpElf
          } each
        }
        # more physical scope dumping, but harder to follow output
        # { :scope
        #   addr peekElf64 %00000000FFFFFFFF band _ "len:" -01 out 8 div 1 -01 range {
        #     8 mul addr add peekElf64 dumpElf
        #   } each
        # }
        { :scope
          addr 8 add peekElf64 ==nameTable
          nameTable { nameTable 8 add peekElf64 %00000000FFFFFFFF band 16 div 1 sub } { 0 } ? * ==nameTableFill

          { ==i
            i nameTableFill lt {
              i 1 add 16 mul nameTable add peekElf64 ==name
              name 24 add peekElf64 256 math .base str .fromArray 0 out
            } rep
          } /dumpLocalName deffst

          addr peekElf64 %00000000FFFFFFFF band 8 div _ ==scopeLen 4 -01 range {
            _ 4 sub dumpLocalName
              8 mul addr add peekElf64 dumpElf
          } each

          addr 24 add peekElf64 ==extensionArea
          extensionArea {
            "<in extension area>" 0 out
            extensionArea peekElf64 %00000000FFFFFFFF band 8 div 1 -01 range {
              _ 1 sub scopeLen add 4 sub dumpLocalName
                8 mul extensionArea add peekElf64 dumpElf
            } each
          } { } ? *

          "<parent>" 0 out
          addr 16 add peekElf64 dumpElf
        }
        { :name_table
          addr 8 add peekElf64 _ "fill:" -01 out 16 div 1 -01 range {
            16 mul addr add peekElf64 dumpElf
          } each
        }
        { :errornous_B }
        { :errornous_C }
        { :errornous_D }
        { :errornous_E }
        { :errornous_F }
      ] * *
    }
  ] conds
  indent 1 sub =indent
} /dumpElf deffst

"=== From current scope ===\n" sys .out .writeall
initialR14 dumpElf
"=== From current data stack ===\n" sys .out .writeall
{ initialRsp %FFFF band } {
  initialRsp peekElf64 dumpElf
  initialRsp 8 add =initialRsp
} loop
"=== From current call stack ===\n" sys .out .writeall
{ initialR15 %FFFF band } {
  initialR15 peekElf64 dumpElf
  initialR15 8 add =initialRsp
} loop

# vim: syn=elymas