mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 12:12:45 +00:00 
			
		
		
		
	UserspaceEmulator: Put the executable name in argv[0] :^)
The emulated program can now find its own name in argv[0]. Very cool!
This commit is contained in:
		
							parent
							
								
									ddf7b817df
								
							
						
					
					
						commit
						079021a607
					
				
					 5 changed files with 23 additions and 6 deletions
				
			
		|  | @ -26,6 +26,7 @@ | |||
| 
 | ||||
| #include "Emulator.h" | ||||
| #include "SoftCPU.h" | ||||
| #include <AK/LexicalPath.h> | ||||
| #include <AK/LogStream.h> | ||||
| #include <Kernel/API/Syscall.h> | ||||
| #include <stdio.h> | ||||
|  | @ -92,9 +93,10 @@ private: | |||
|     u8* m_data { nullptr }; | ||||
| }; | ||||
| 
 | ||||
| Emulator::Emulator(NonnullRefPtr<ELF::Loader> elf) | ||||
| Emulator::Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader> elf) | ||||
|     : m_elf(move(elf)) | ||||
|     , m_cpu(*this) | ||||
|     , m_executable_path(executable_path) | ||||
| { | ||||
|     setup_stack(); | ||||
| } | ||||
|  | @ -105,16 +107,19 @@ void Emulator::setup_stack() | |||
|     m_mmu.add_region(move(stack_region)); | ||||
|     m_cpu.set_esp(stack_location + stack_size); | ||||
| 
 | ||||
|     m_cpu.push_string(LexicalPath(m_executable_path).basename()); | ||||
|     u32 argv0 = m_cpu.esp(); | ||||
| 
 | ||||
|     m_cpu.push32(0); // char** envp = { nullptr }
 | ||||
|     u32 envp = m_cpu.esp(); | ||||
| 
 | ||||
|     m_cpu.push32(0); // char** argv = { nullptr }
 | ||||
|     m_cpu.push32(0); // char** argv = { argv0, nullptr }
 | ||||
|     m_cpu.push32(argv0); | ||||
|     u32 argv = m_cpu.esp(); | ||||
| 
 | ||||
|     m_cpu.push32(0); // (alignment)
 | ||||
|     m_cpu.push32(0); // (alignment)
 | ||||
| 
 | ||||
|     u32 argc = 0; | ||||
|     u32 argc = 1; | ||||
|     m_cpu.push32(envp); | ||||
|     m_cpu.push32(argv); | ||||
|     m_cpu.push32(argc); | ||||
|  |  | |||
|  | @ -37,7 +37,7 @@ namespace UserspaceEmulator { | |||
| 
 | ||||
| class Emulator { | ||||
| public: | ||||
|     explicit Emulator(NonnullRefPtr<ELF::Loader>); | ||||
|     Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader>); | ||||
| 
 | ||||
|     bool load_elf(); | ||||
|     void dump_backtrace(); | ||||
|  | @ -63,6 +63,8 @@ private: | |||
| 
 | ||||
|     bool m_shutdown { false }; | ||||
|     int m_exit_status { 0 }; | ||||
| 
 | ||||
|     String m_executable_path; | ||||
| }; | ||||
| 
 | ||||
| } | ||||
|  |  | |||
|  | @ -139,6 +139,14 @@ void SoftCPU::write_memory32(X86::LogicalAddress address, u32 value) | |||
|     m_emulator.mmu().write32(address, value); | ||||
| } | ||||
| 
 | ||||
| void SoftCPU::push_string(const StringView& string) | ||||
| { | ||||
|     size_t space_to_allocate = round_up_to_power_of_two(string.length() + 1, 16); | ||||
|     set_esp(esp() - space_to_allocate); | ||||
|     m_emulator.mmu().copy_to_vm(esp(), string.characters_without_null_termination(), string.length()); | ||||
|     m_emulator.mmu().write8({ 0x20, esp() + string.length() }, '\0'); | ||||
| } | ||||
| 
 | ||||
| void SoftCPU::push32(u32 value) | ||||
| { | ||||
|     set_esp(esp() - sizeof(value)); | ||||
|  |  | |||
|  | @ -75,6 +75,8 @@ public: | |||
|     void push32(u32); | ||||
|     u32 pop32(); | ||||
| 
 | ||||
|     void push_string(const StringView&); | ||||
| 
 | ||||
|     u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; } | ||||
|     u16& segment(X86::SegmentRegister seg) { return m_segment[(int)seg]; } | ||||
| 
 | ||||
|  |  | |||
|  | @ -47,7 +47,7 @@ int main(int argc, char** argv) | |||
| 
 | ||||
|     auto elf = ELF::Loader::create((const u8*)mapped_file.data(), mapped_file.size()); | ||||
| 
 | ||||
|     UserspaceEmulator::Emulator emulator(move(elf)); | ||||
|     UserspaceEmulator::Emulator emulator(executable_path, move(elf)); | ||||
|     if (!emulator.load_elf()) | ||||
|         return 1; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling