Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2816 | clevermous | 1 | ; Platform-specific procedures for Linux. |
2 | |||
3 | ; Reallocate memory at pointer [start.buf] and size [start.allocated], |
||
4 | ; new size is in eax. |
||
5 | realloc: |
||
6 | push ebx esi edi |
||
7 | mov ecx, eax |
||
8 | push ebp |
||
9 | kercall __NR_mmap2, 0, , PROT_READ+PROT_WRITE, MAP_PRIVATE+MAP_ANONYMOUS, -1, 0 |
||
10 | pop ebp |
||
11 | cmp eax, 0xFFFFF000 |
||
12 | ja nomemory |
||
13 | add [start.free], ecx |
||
14 | xchg ecx, [start.allocated] |
||
15 | sub [start.free], ecx |
||
16 | mov edi, eax |
||
17 | xchg eax, [start.buf] |
||
18 | shr ecx, 2 |
||
19 | jz .nothing |
||
20 | push ecx |
||
21 | mov esi, eax |
||
22 | rep movsd |
||
23 | pop ecx |
||
24 | shl ecx, 2 |
||
25 | call free_eax_ecx |
||
26 | .nothing: |
||
27 | pop edi esi ebx |
||
28 | ret |
||
29 | |||
30 | ; Read the next portion of input data to [start.buf]. |
||
31 | read: |
||
32 | mov ecx, [start.buf] |
||
33 | add ecx, [start.allocated] |
||
34 | mov edx, [start.free] |
||
35 | sub ecx, edx |
||
36 | kercall __NR_read, [start.in], , |
||
37 | test eax, eax |
||
38 | js readerr |
||
39 | ret |
||
40 | |||
41 | ; Write output data: eax=pointer, edi=size. |
||
42 | write: |
||
43 | mov ecx, eax |
||
44 | kercall __NR_write, [start.out], , edi |
||
45 | cmp eax, edi |
||
46 | jnz writeerr |
||
47 | ret |
||
48 | |||
49 | ; Parse command line, open input and output files. |
||
50 | get_params: |
||
51 | ; 1. Initialize default streams: 0 for stdin, 1 for stdout. |
||
52 | inc [start.out] |
||
53 | ; 2. Prepare for scanning, skipping argv[0]. |
||
54 | mov ebx, [start.argc] |
||
55 | cmp ebx, 1 |
||
56 | jbe .noargs |
||
57 | dec ebx |
||
58 | lea esi, [start.argv+4] ; skip argv[0] |
||
59 | xor edi, edi ; no args parsed yet |
||
60 | ; 3. Parse loop. |
||
61 | .parse: |
||
62 | ; 3a. Get the next argument. |
||
63 | lodsd |
||
64 | ; 3b. Check whether it is a known option. |
||
65 | cmp word [eax], '-e' |
||
66 | jnz @f |
||
67 | cmp byte [eax+2], 0 |
||
68 | jnz @f |
||
69 | ; 3c. If it is, modify flags and continue the loop. |
||
70 | mov [start.flags], 1 ; '-e' is given |
||
71 | jmp .nextarg |
||
72 | @@: |
||
73 | ; 3d. Otherwise, it is a name of input or output file. |
||
74 | ; edi keeps the count of names encountered before; |
||
75 | ; edi = 0 means this is input file, edi = 1 - output file, |
||
76 | ; otherwise this is third arg, which is an error |
||
77 | cmp edi, 1 |
||
78 | ja information |
||
79 | ; 3e. Some parameters of __NR_open differ for input and output. Setup them. |
||
80 | mov ecx, O_WRONLY+O_CREAT+O_TRUNC |
||
81 | mov edx, 0644o |
||
82 | jz @f |
||
83 | mov ecx, O_RDONLY |
||
84 | @@: |
||
85 | ; 3f. Open/create the file, save the handle. |
||
86 | push ebx |
||
87 | mov ebx, eax |
||
88 | kercall __NR_open |
||
89 | pop ebx |
||
90 | test eax, eax |
||
91 | js .fileerr |
||
92 | mov [start.in+edi*4], eax |
||
93 | inc edi |
||
94 | .nextarg: |
||
95 | dec ebx |
||
96 | jnz .parse |
||
97 | .noargs: |
||
98 | ; 4. End of command line reached. Return. |
||
99 | ret |
||
100 | .fileerr: |
||
101 | test edi, edi |
||
102 | jz in_openerr |
||
103 | jmp out_openerr |
||
104 | |||
105 | ; Exit, return code is in al. |
||
106 | exit: |
||
107 | movzx ebx, al |
||
108 | push ebx |
||
109 | mov eax, [start.buf] |
||
110 | test eax, eax |
||
111 | jz @f |
||
112 | mov ecx, [start.allocated] |
||
113 | call free_eax_ecx |
||
114 | @@: |
||
115 | kercall __NR_close, [start.in] |
||
116 | kercall __NR_close, [start.out] |
||
117 | pop ebx |
||
118 | kercall __NR_exit |
||
119 | |||
120 | ; Helper procedure for realloc and exit. |
||
121 | free_eax_ecx: |
||
122 | mov ebx, eax |
||
123 | kercall __NR_munmap |
||
124 | ret |
||
125 | |||
126 | ; Output the message given in esi to stderr. |
||
127 | sayerr: |
||
128 | movzx edx, byte [esi-1] |
||
129 | kercall __NR_write, 2, esi, |
||
130 | ret |
||
131 | |||
132 | ; Get environment variable esi (ebx-relative pointer) to the buffer, |
||
133 | ; expanding it if needed. |
||
134 | get_environment_variable: |
||
135 | mov ecx, [start.argc] |
||
136 | lea ecx, [start.argv+ecx*4+4] |
||
137 | .findvar: |
||
138 | mov edx, [ecx] |
||
139 | add ecx, 4 |
||
140 | test edx, edx |
||
141 | jz .notfound |
||
142 | push esi |
||
143 | add esi, ebx |
||
144 | .comparename: |
||
145 | lodsb |
||
146 | cmp al, [edx] |
||
147 | jnz @f |
||
148 | inc edx |
||
149 | jmp .comparename |
||
150 | @@: |
||
151 | pop esi |
||
152 | test al, al |
||
153 | jnz .findvar |
||
154 | cmp byte [edx], '=' |
||
155 | jnz .findvar |
||
156 | inc edx |
||
157 | xor eax, eax |
||
158 | @@: |
||
159 | inc eax |
||
160 | cmp byte [edx+eax-1], 0 |
||
161 | jnz @b |
||
162 | stdcall alloc_in_buf, eax |
||
163 | @@: |
||
164 | mov al, [edx] |
||
165 | inc edx |
||
166 | mov [edi+ebx], al |
||
167 | inc edi |
||
168 | test al, al |
||
169 | jnz @b |
||
170 | ret |
||
171 | .notfound: |
||
172 | stdcall alloc_in_buf, 1 |
||
173 | mov byte [edi+ebx], 0 |
||
174 | inc edi |
||
175 | ret |
||
176 | |||
177 | ; Test whether a file with name [.testname] exists. |
||
178 | ; Returns eax<0 if not, nonzero otherwise. |
||
179 | test_file_exists: |
||
180 | push ebx |
||
181 | add ebx, [start.testname] |
||
182 | sub esp, 800h |
||
183 | kercall __NR_stat, , esp |
||
184 | add esp, 800h |
||
185 | pop ebx |
||
186 | ret0> |