24.01.2014 Views

Codice

Codice

Codice

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

278 volume VI os16<br />

Script e sorgenti del kernel 279<br />

1860061 | arg = arg_data;<br />

1860062 | for (i = 0, j = 0; i < argc; i++)<br />

1860063 | {<br />

1860064 | argv[i] = (char *) j; // Relative pointer inside<br />

1860065 | // the ‘arg_data’.<br />

1860066 | size = strlen (arg);<br />

1860067 | arg += size + 1;<br />

1860068 | j += size + 1;<br />

1860069 | }<br />

1860070 | arg_data_size = j;<br />

1860071 | if (arg_data_size % 2)<br />

1860072 | {<br />

1860073 | arg_data_size++;<br />

1860074 | }<br />

1860075 | //<br />

1860076 | // Scan environment variables to calculate the full size and the<br />

1860077 | // relative pointers. The final size is rounded to 2, for the stack.<br />

1860078 | //<br />

1860079 | env = env_data;<br />

1860080 | for (i = 0, j = 0; i < envc; i++)<br />

1860081 | {<br />

1860082 | envp[i] = (char *) j; // Relative pointer inside<br />

1860083 | // the ‘env_data’.<br />

1860084 | size = strlen (env);<br />

1860085 | env += size + 1;<br />

1860086 | j += size + 1;<br />

1860087 | }<br />

1860088 | env_data_size = j;<br />

1860089 | if (env_data_size % 2)<br />

1860090 | {<br />

1860091 | env_data_size++;<br />

1860092 | }<br />

1860093 | //<br />

1860094 | // Read the inode related to the executable file name.<br />

1860095 | // Function path_inode() includes the inode get procedure.<br />

1860096 | //<br />

1860097 | inode = path_inode (pid, path);<br />

1860098 | if (inode == NULL)<br />

1860099 | {<br />

1860100 | errset (ENOENT); // No such file or directory.<br />

1860101 | return (-1);<br />

1860102 | }<br />

1860103 | //<br />

1860104 | // Check for permissions.<br />

1860105 | //<br />

1860106 | status = inode_check (inode, S_IFREG, 5, proc_table[pid].euid);<br />

1860107 | if (status != 0)<br />

1860108 | {<br />

1860109 | //<br />

1860110 | // File is not of a valid type or permission are not<br />

1860111 | // sufficient: release the executable file inode<br />

1860112 | // and return with an error.<br />

1860113 | //<br />

1860114 | inode_put (inode);<br />

1860115 | errset (EACCES); // Permission denied.<br />

1860116 | return (-1);<br />

1860117 | }<br />

1860118 | //<br />

1860119 | // Read the header from the executable file.<br />

1860120 | //<br />

1860121 | size_read = inode_file_read (inode, (off_t) 0, &header,<br />

1860122 | (sizeof header), &eof);<br />

1860123 | if (size_read != (sizeof header))<br />

1860124 | {<br />

1860125 | //<br />

1860126 | // The file is shorter than the executable header, so, it isn’t<br />

1860127 | // an executable: release the file inode and return with an<br />

1860128 | // error.<br />

1860129 | //<br />

1860130 | inode_put (inode);<br />

1860131 | errset (ENOEXEC);<br />

1860132 | return (-1);<br />

1860133 | }<br />

1860134 | if (header.magic0 != MAGIC_OS16 || header.magic1 != MAGIC_OS16_APPL)<br />

1860135 | {<br />

1860136 | //<br />

1860137 | // The header does not have the expected magic numbers, so,<br />

1860138 | // it isn’t a valid executable: release the file inode and<br />

1860139 | // return with an error.<br />

1860140 | //<br />

1860141 | inode_put (inode);<br />

1860142 | errset (ENOEXEC);<br />

1860143 | return (-1); // This is not a valid executable!<br />

1860144 | }<br />

1860145 | //<br />

1860146 | // Calculate data size.<br />

1860147 | //<br />

1860148 | s = header.ebss;<br />

1860149 | if (header.ssize == 0)<br />

1860150 | {<br />

1860151 | s += 0x10000L; // Zero means max size.<br />

1860152 | }<br />

1860153 | else<br />

1860154 | {<br />

1860155 | s += header.ssize;<br />

1860156 | }<br />

1860157 | if (s > 0xFFFF)<br />

1860158 | {<br />

1860159 | process_size_d = 0x0000; // 0x0000 means the maximum size:<br />

1860160 | // 0x10000.<br />

1860161 | new_sp = 0x0000; // 0x0000 is like 0x10000 and the first<br />

1860162 | // push moves SP to 0xFFFE.<br />

1860163 | }<br />

1860164 | else<br />

1860165 | {<br />

1860166 | process_size_d = s;<br />

1860167 | new_sp = process_size_d;<br />

1860168 | if (new_sp % 2)<br />

1860169 | {<br />

1860170 | new_sp--; // The stack pointer should be even.<br />

1860171 | }<br />

1860172 | }<br />

1860173 | //<br />

1860174 | // Calculate code size.<br />

1860175 | //<br />

1860176 | if (header.segoff == 0)<br />

1860177 | {<br />

1860178 | process_size_i = process_size_d;<br />

1860179 | }<br />

1860180 | else<br />

1860181 | {<br />

1860182 | process_size_i = header.segoff * 16;<br />

1860183 | }<br />

1860184 | //<br />

1860185 | // Allocate memory: code and data segments.<br />

1860186 | //<br />

1860187 | status = mb_alloc_size (process_size_i, &allocated_i);<br />

1860188 | if (status < 0)<br />

1860189 | {<br />

1860190 | //<br />

1860191 | // The program instructions (code segment) cannot be loaded<br />

1860192 | // into memory: release the executable file inode and return<br />

1860193 | // with an error.<br />

1860194 | //<br />

1860195 | inode_put (inode);<br />

1860196 | errset (ENOMEM); // Not enough space.<br />

1860197 | return ((pid_t) -1);<br />

1860198 | }<br />

1860199 | if (header.segoff == 0)<br />

1860200 | {<br />

1860201 | //<br />

1860202 | // Code and data segments are the same: no need<br />

1860203 | // to allocate more memory for the data segment.<br />

1860204 | //<br />

1860205 | allocated_d.address = allocated_i.address;<br />

1860206 | allocated_d.segment = allocated_i.segment;<br />

1860207 | allocated_d.size = allocated_i.size;<br />

1860208 | }<br />

1860209 | else<br />

1860210 | {<br />

1860211 | //<br />

1860212 | // Code and data segments are different: the data<br />

1860213 | // segment memory is allocated.<br />

1860214 | //<br />

1860215 | status = mb_alloc_size (process_size_d, &allocated_d);<br />

1860216 | if (status < 0)<br />

1860217 | {<br />

1860218 | //<br />

1860219 | // The separated program data (data segment) cannot be loaded<br />

1860220 | // into memory: free the already allocated memory for the<br />

1860221 | // program instructions, release the executable file inode<br />

1860222 | // and return with an error.<br />

1860223 | //<br />

1860224 | mb_free (allocated_i.address, allocated_i.size);<br />

1860225 | inode_put (inode);<br />

1860226 | errset (ENOMEM); // Not enough space.<br />

1860227 | return ((pid_t) -1);<br />

1860228 | }<br />

1860229 | }<br />

1860230 | //<br />

1860231 | // Load executable in memory.<br />

1860232 | //<br />

1860233 | if (header.segoff == 0)<br />

1860234 | {<br />

1860235 | //<br />

1860236 | // Code and data share the same segment.<br />

1860237 | //<br />

1860238 | for (eof = 0, memory_start = allocated_i.address,<br />

1860239 | inode_start = 0, size_read = 0;<br />

1860240 | inode_start < inode->size && !eof;<br />

1860241 | inode_start += size_read)<br />

1860242 | {<br />

1860243 | memory_start += size_read;<br />

1860244 | //<br />

1860245 | // Read a block of memory.<br />

1860246 | //<br />

1860247 | size_read = inode_file_read (inode, inode_start,<br />

1860248 | buffer, MEM_BLOCK_SIZE, &eof);<br />

1860249 | if (size_read < 0)<br />

1860250 | {<br />

1860251 | //<br />

1860252 | // Free memory and inode.<br />

1860253 | //<br />

1860254 | mb_free (allocated_i.address, allocated_i.size);<br />

1860255 | inode_put (inode);<br />

1860256 | errset (EIO);<br />

1860257 | return (-1);<br />

1860258 | }<br />

1860259 | //<br />

1860260 | // Copy inside the right position to be executed.<br />

1860261 | //<br />

1860262 | dev_io ((pid_t) 0, DEV_MEM, DEV_WRITE, memory_start, buffer,<br />

1860263 | (size_t) size_read, NULL);<br />

1860264 | }<br />

1860265 | }<br />

1860266 | else<br />

1860267 | {<br />

1860268 | //<br />

1860269 | // Code and data with different segments.<br />

1860270 | //<br />

1860271 | for (eof = 0, memory_start = allocated_i.address,<br />

1860272 | inode_start = 0, size_read = 0;<br />

1860273 | inode_start < process_size_i && !eof;<br />

1860274 | inode_start += size_read)<br />

1860275 | {<br />

1860276 | memory_start += size_read;<br />

1860277 | //<br />

1860278 | // Read a block of memory<br />

1860279 | //<br />

1860280 | size_read = inode_file_read (inode, inode_start,<br />

1860281 | buffer, MEM_BLOCK_SIZE, &eof);<br />

1860282 | if (size_read < 0)<br />

1860283 | {<br />

1860284 | //<br />

1860285 | // Free memory and inode.<br />

1860286 | //<br />

1860287 | mb_free (allocated_i.address, allocated_i.size);<br />

1860288 | mb_free (allocated_d.address, allocated_d.size);<br />

1860289 | inode_put (inode);<br />

1860290 | errset (EIO);<br />

1860291 | return (-1);<br />

1860292 | }

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!