| 
						
						
						
						 |  | @@ -1,55 +1,56 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include "semihosting.h" |  |  |  | #include "semihosting.h" | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <cstdint> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <map> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <iss/vm_types.h> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <stdexcept> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <chrono> |  |  |  | #include <chrono> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <cstdint> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <iss/vm_types.h> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <map> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #include <stdexcept> | 
			
		
	
		
		
			
				
					
					|  |  |  | // explanation of syscalls can be found at https://github.com/SpinalHDL/openocd_riscv/blob/riscv_spinal/src/target/semihosting_common.h |  |  |  | // explanation of syscalls can be found at https://github.com/SpinalHDL/openocd_riscv/blob/riscv_spinal/src/target/semihosting_common.h | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | const char *SYS_OPEN_MODES_STRS[] = { "r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b" }; |  |  |  | const char* SYS_OPEN_MODES_STRS[] = {"r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b"}; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, int len=4) { |  |  |  | template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, int len = 4) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     uint8_t bytes[4]; |  |  |  |     uint8_t bytes[4]; | 
			
		
	
		
		
			
				
					
					|  |  |  |     auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr, 4, &bytes[0]); |  |  |  |     auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr, 4, &bytes[0]); | 
			
		
	
		
		
			
				
					
					|  |  |  |     //auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, *parameter, 1, &character); |  |  |  |     // auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, *parameter, 1, &character); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(res != iss::Ok){ |  |  |  |     if(res != iss::Ok) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         return 0; //TODO THROW ERROR |  |  |  |         return 0; // TODO THROW ERROR | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     } else return static_cast<T>(bytes[0]) | (static_cast<T>(bytes[1]) << 8) | (static_cast<T>(bytes[2]) << 16) | (static_cast<T>(bytes[3]) << 24); |  |  |  |     } else | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         return static_cast<T>(bytes[0]) | (static_cast<T>(bytes[1]) << 8) | (static_cast<T>(bytes[2]) << 16) | | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                (static_cast<T>(bytes[3]) << 24); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | template <typename T> std::string sh_read_string(iss::arch_if* arch_if_ptr, T addr, T str_len){ |  |  |  | template <typename T> std::string sh_read_string(iss::arch_if* arch_if_ptr, T addr, T str_len) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     std::vector<uint8_t> buffer(str_len); |  |  |  |     std::vector<uint8_t> buffer(str_len); | 
			
		
	
		
		
			
				
					
					|  |  |  |     for (int i = 0; i < str_len; i++ ) { |  |  |  |     for(int i = 0; i < str_len; i++) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         buffer[i] = sh_read_field(arch_if_ptr, addr + i, 1); |  |  |  |         buffer[i] = sh_read_field(arch_if_ptr, addr + i, 1); | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     std::string str(buffer.begin(), buffer.end()); |  |  |  |     std::string str(buffer.begin(), buffer.end()); | 
			
		
	
		
		
			
				
					
					|  |  |  |     return str; |  |  |  |     return str; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter) { |  |  |  | template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arch_if_ptr, T* call_number, T* parameter) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     static std::map<T, FILE *> openFiles; |  |  |  |     static std::map<T, FILE*> openFiles; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     static T file_count = 3; |  |  |  |     static T file_count = 3; | 
			
		
	
		
		
			
				
					
					|  |  |  |     static T semihostingErrno; |  |  |  |     static T semihostingErrno; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     switch(static_cast<semihosting_syscalls>(*call_number)) { |  |  |  |     switch(static_cast<semihosting_syscalls>(*call_number)) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_CLOCK: { |  |  |  |     case semihosting_syscalls::SYS_CLOCK: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto end = std::chrono::high_resolution_clock::now(); // end measurement  |  |  |  |         auto end = std::chrono::high_resolution_clock::now(); // end measurement | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         auto elapsed = end - timeVar; |  |  |  |         auto elapsed = end - timeVar; | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); |  |  |  |         auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         *call_number = millis; //TODO get time now |  |  |  |         *call_number = millis; // TODO get time now | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_CLOSE: { |  |  |  |     case semihosting_syscalls::SYS_CLOSE: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T file_handle = *parameter; |  |  |  |         T file_handle = *parameter; | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (openFiles.size() <= file_handle && file_handle < 0) { |  |  |  |         if(openFiles.size() <= file_handle && file_handle < 0) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             semihostingErrno = EBADF; |  |  |  |             semihostingErrno = EBADF; | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto file = openFiles[file_handle]; |  |  |  |         auto file = openFiles[file_handle]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         openFiles.erase(file_handle); |  |  |  |         openFiles.erase(file_handle); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (!(file == stdin || file == stdout || file == stderr)) { |  |  |  |         if(!(file == stdin || file == stdout || file == stderr)) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             int i = fclose(file); |  |  |  |             int i = fclose(file); | 
			
		
	
		
		
			
				
					
					|  |  |  |             *call_number = i; |  |  |  |             *call_number = i; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else { |  |  |  |         } else { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -80,7 +81,8 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto file = openFiles[file_handle]; |  |  |  |         auto file = openFiles[file_handle]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         size_t currentPos = ftell(file); |  |  |  |         size_t currentPos = ftell(file); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (currentPos < 0) throw std::runtime_error("SYS_FLEN negative value"); |  |  |  |         if(currentPos < 0) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::runtime_error("SYS_FLEN negative value"); | 
			
		
	
		
		
			
				
					
					|  |  |  |         fseek(file, 0, SEEK_END); |  |  |  |         fseek(file, 0, SEEK_END); | 
			
		
	
		
		
			
				
					
					|  |  |  |         size_t length = ftell(file); |  |  |  |         size_t length = ftell(file); | 
			
		
	
		
		
			
				
					
					|  |  |  |         fseek(file, currentPos, SEEK_SET); |  |  |  |         fseek(file, currentPos, SEEK_SET); | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -101,36 +103,36 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_ISTTY: { |  |  |  |     case semihosting_syscalls::SYS_ISTTY: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T file_handle = *parameter;        |  |  |  |         T file_handle = *parameter; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         *call_number = (file_handle == 0 || file_handle == 1 || file_handle == 2); |  |  |  |         *call_number = (file_handle == 0 || file_handle == 1 || file_handle == 2); | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_OPEN: { |  |  |  |     case semihosting_syscalls::SYS_OPEN: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T mode = sh_read_field<T>(arch_if_ptr, 4+(*parameter)); |  |  |  |         T mode = sh_read_field<T>(arch_if_ptr, 4 + (*parameter)); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         T path_len = sh_read_field<T>(arch_if_ptr, 8+(*parameter)); |  |  |  |         T path_len = sh_read_field<T>(arch_if_ptr, 8 + (*parameter)); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len); |  |  |  |         std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         //TODO LOG INFO |  |  |  |         // TODO LOG INFO | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (mode >= 12) { |  |  |  |         if(mode >= 12) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             //TODO throw ERROR |  |  |  |             // TODO throw ERROR | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         FILE *file = nullptr; |  |  |  |         FILE* file = nullptr; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         if(path_str == ":tt") { |  |  |  |         if(path_str == ":tt") { | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (mode < 4) |  |  |  |             if(mode < 4) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 file = stdin; |  |  |  |                 file = stdin; | 
			
		
	
		
		
			
				
					
					|  |  |  |             else if (mode < 8)  |  |  |  |             else if(mode < 8) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 file = stdout; |  |  |  |                 file = stdout; | 
			
		
	
		
		
			
				
					
					|  |  |  |             else  |  |  |  |             else | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 file = stderr; |  |  |  |                 file = stderr; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else { |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |             file = fopen(path_str.c_str(), SYS_OPEN_MODES_STRS[mode]); |  |  |  |             file = fopen(path_str.c_str(), SYS_OPEN_MODES_STRS[mode]); | 
			
		
	
		
		
			
				
					
					|  |  |  |             if (file == nullptr) { |  |  |  |             if(file == nullptr) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 //TODO throw error |  |  |  |                 // TODO throw error | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -138,45 +140,41 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |         openFiles[file_handle] = file; |  |  |  |         openFiles[file_handle] = file; | 
			
		
	
		
		
			
				
					
					|  |  |  |         *call_number = file_handle; |  |  |  |         *call_number = file_handle; | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_READ: { |  |  |  |     case semihosting_syscalls::SYS_READ: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter)+4); |  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         T addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T count = sh_read_field<T>(arch_if_ptr, (*parameter)+8); |  |  |  |         T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto file = openFiles[file_handle]; |  |  |  |         auto file = openFiles[file_handle]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         std::vector<uint8_t> buffer(count); |  |  |  |         std::vector<uint8_t> buffer(count); | 
			
		
	
		
		
			
				
					
					|  |  |  |         size_t num_read = 0; |  |  |  |         size_t num_read = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (file == stdin) |  |  |  |         if(file == stdin) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             // when reading from stdin: mimic behaviour from read syscall |  |  |  |             // when reading from stdin: mimic behaviour from read syscall | 
			
		
	
		
		
			
				
					
					|  |  |  |             // and return on newline. |  |  |  |             // and return on newline. | 
			
		
	
		
		
			
				
					
					|  |  |  |             while (num_read < count) |  |  |  |             while(num_read < count) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             { |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                 char c = fgetc(file); |  |  |  |                 char c = fgetc(file); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 buffer[num_read] = c; |  |  |  |                 buffer[num_read] = c; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 num_read++; |  |  |  |                 num_read++; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if (c == '\n') |  |  |  |                 if(c == '\n') | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                     break; |  |  |  |                     break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |         } else { |  |  |  |         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |             num_read = fread(buffer.data(), 1, count, file); |  |  |  |             num_read = fread(buffer.data(), 1, count, file); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         buffer.resize(num_read); |  |  |  |         buffer.resize(num_read); | 
			
		
	
		
		
			
				
					
					|  |  |  |         for(int i  = 0; i<num_read; i++) { |  |  |  |         for(int i = 0; i < num_read; i++) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr+i, 1, &buffer[i]); |  |  |  |             auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, addr + i, 1, &buffer[i]); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             if(res != iss::Ok) |  |  |  |             if(res != iss::Ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 return; |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         *call_number = count - num_read; |  |  |  |         *call_number = count - num_read; | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_READC: { |  |  |  |     case semihosting_syscalls::SYS_READC: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         uint8_t character = getchar(); |  |  |  |         uint8_t character = getchar(); | 
			
		
	
		
		
			
				
					
					|  |  |  |         //character = getchar(); |  |  |  |         // character = getchar(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         /*if(character != iss::Ok) |  |  |  |         /*if(character != iss::Ok) | 
			
		
	
		
		
			
				
					
					|  |  |  |             std::cout << "Not OK"; |  |  |  |             std::cout << "Not OK"; | 
			
		
	
		
		
			
				
					
					|  |  |  |             return;*/ |  |  |  |             return;*/ | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -185,36 +183,38 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_REMOVE: { |  |  |  |     case semihosting_syscalls::SYS_REMOVE: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T path_str_addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T path_len = sh_read_field<T>(arch_if_ptr, (*parameter)+4); |  |  |  |         T path_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 4); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len); |  |  |  |         std::string path_str = sh_read_string<T>(arch_if_ptr, path_str_addr, path_len); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(remove(path_str.c_str())<0) *call_number = -1; |  |  |  |         if(remove(path_str.c_str()) < 0) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             *call_number = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_RENAME: { |  |  |  |     case semihosting_syscalls::SYS_RENAME: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T path_str_addr_old = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T path_str_addr_old = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T path_len_old = sh_read_field<T>(arch_if_ptr, (*parameter)+4); |  |  |  |         T path_len_old = sh_read_field<T>(arch_if_ptr, (*parameter) + 4); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         T path_str_addr_new = sh_read_field<T>(arch_if_ptr, (*parameter)+8); |  |  |  |         T path_str_addr_new = sh_read_field<T>(arch_if_ptr, (*parameter) + 8); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         T path_len_new = sh_read_field<T>(arch_if_ptr, (*parameter)+12); |  |  |  |         T path_len_new = sh_read_field<T>(arch_if_ptr, (*parameter) + 12); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         std::string path_str_old = sh_read_string<T>(arch_if_ptr, path_str_addr_old, path_len_old); |  |  |  |         std::string path_str_old = sh_read_string<T>(arch_if_ptr, path_str_addr_old, path_len_old); | 
			
		
	
		
		
			
				
					
					|  |  |  |         std::string path_str_new = sh_read_string<T>(arch_if_ptr, path_str_addr_new, path_len_new);  |  |  |  |         std::string path_str_new = sh_read_string<T>(arch_if_ptr, path_str_addr_new, path_len_new); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         rename(path_str_old.c_str(), path_str_new.c_str());        |  |  |  |         rename(path_str_old.c_str(), path_str_new.c_str()); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_SEEK: { |  |  |  |     case semihosting_syscalls::SYS_SEEK: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T pos = sh_read_field<T>(arch_if_ptr, (*parameter)+1); |  |  |  |         T pos = sh_read_field<T>(arch_if_ptr, (*parameter) + 1); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         auto file = openFiles[file_handle]; |  |  |  |         auto file = openFiles[file_handle]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         int retval = fseek(file, pos, SEEK_SET); |  |  |  |         int retval = fseek(file, pos, SEEK_SET); | 
			
		
	
		
		
			
				
					
					|  |  |  |         if(retval<0) throw std::runtime_error("SYS_SEEK negative return value"); |  |  |  |         if(retval < 0) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             throw std::runtime_error("SYS_SEEK negative return value"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_SYSTEM: { |  |  |  |     case semihosting_syscalls::SYS_SYSTEM: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T cmd_addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T cmd_addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T cmd_len = sh_read_field<T>(arch_if_ptr, (*parameter)+1);  |  |  |  |         T cmd_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 1); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         std::string cmd = sh_read_string<T>(arch_if_ptr, cmd_addr, cmd_len); |  |  |  |         std::string cmd = sh_read_string<T>(arch_if_ptr, cmd_addr, cmd_len); | 
			
		
	
		
		
			
				
					
					|  |  |  |         system(cmd.c_str()); |  |  |  |         system(cmd.c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -224,16 +224,16 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_TIME: { |  |  |  |     case semihosting_syscalls::SYS_TIME: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         //returns time in seconds scince 01.01.1970 00:00 |  |  |  |         // returns time in seconds scince 01.01.1970 00:00 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         *call_number = time(NULL); |  |  |  |         *call_number = time(NULL); | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_TMPNAM: { |  |  |  |     case semihosting_syscalls::SYS_TMPNAM: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T buffer_addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T buffer_addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T identifier = sh_read_field<T>(arch_if_ptr, (*parameter)+1); |  |  |  |         T identifier = sh_read_field<T>(arch_if_ptr, (*parameter) + 1); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         T buffer_len = sh_read_field<T>(arch_if_ptr, (*parameter)+2); |  |  |  |         T buffer_len = sh_read_field<T>(arch_if_ptr, (*parameter) + 2); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         if (identifier > 255) { |  |  |  |         if(identifier > 255) { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |             *call_number = -1; |  |  |  |             *call_number = -1; | 
			
		
	
		
		
			
				
					
					|  |  |  |             return; |  |  |  |             return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -243,15 +243,16 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         for(int i = 0; i < buffer_len; i++) { |  |  |  |         for(int i = 0; i < buffer_len; i++) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             uint8_t character = filename[i]; |  |  |  |             uint8_t character = filename[i]; | 
			
		
	
		
		
			
				
					
					|  |  |  |             auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, (*parameter)+i, 1, &character); |  |  |  |             auto res = arch_if_ptr->write(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, (*parameter) + i, 1, &character); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |             if(res != iss::Ok) return; |  |  |  |             if(res != iss::Ok) | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 return; | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         break; |  |  |  |         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     case semihosting_syscalls::SYS_WRITE: { |  |  |  |     case semihosting_syscalls::SYS_WRITE: { | 
			
		
	
		
		
			
				
					
					|  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter)+4); |  |  |  |         T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |         T addr = sh_read_field<T>(arch_if_ptr, *parameter); |  |  |  |         T addr = sh_read_field<T>(arch_if_ptr, *parameter); | 
			
		
	
		
		
			
				
					
					|  |  |  |         T count = sh_read_field<T>(arch_if_ptr, (*parameter)+8); |  |  |  |         T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         auto file = openFiles[file_handle]; |  |  |  |         auto file = openFiles[file_handle]; | 
			
		
	
		
		
			
				
					
					|  |  |  |         std::string str = sh_read_string<T>(arch_if_ptr, addr, count); |  |  |  |         std::string str = sh_read_string<T>(arch_if_ptr, addr, count); | 
			
		
	
	
		
		
			
				
					
					|  |  |   |