mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 03:32: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 "Emulator.h" | ||||||
| #include "SoftCPU.h" | #include "SoftCPU.h" | ||||||
|  | #include <AK/LexicalPath.h> | ||||||
| #include <AK/LogStream.h> | #include <AK/LogStream.h> | ||||||
| #include <Kernel/API/Syscall.h> | #include <Kernel/API/Syscall.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | @ -92,9 +93,10 @@ private: | ||||||
|     u8* m_data { nullptr }; |     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_elf(move(elf)) | ||||||
|     , m_cpu(*this) |     , m_cpu(*this) | ||||||
|  |     , m_executable_path(executable_path) | ||||||
| { | { | ||||||
|     setup_stack(); |     setup_stack(); | ||||||
| } | } | ||||||
|  | @ -105,16 +107,19 @@ void Emulator::setup_stack() | ||||||
|     m_mmu.add_region(move(stack_region)); |     m_mmu.add_region(move(stack_region)); | ||||||
|     m_cpu.set_esp(stack_location + stack_size); |     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 }
 |     m_cpu.push32(0); // char** envp = { nullptr }
 | ||||||
|     u32 envp = m_cpu.esp(); |     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(); |     u32 argv = m_cpu.esp(); | ||||||
| 
 | 
 | ||||||
|     m_cpu.push32(0); // (alignment)
 |  | ||||||
|     m_cpu.push32(0); // (alignment)
 |     m_cpu.push32(0); // (alignment)
 | ||||||
| 
 | 
 | ||||||
|     u32 argc = 0; |     u32 argc = 1; | ||||||
|     m_cpu.push32(envp); |     m_cpu.push32(envp); | ||||||
|     m_cpu.push32(argv); |     m_cpu.push32(argv); | ||||||
|     m_cpu.push32(argc); |     m_cpu.push32(argc); | ||||||
|  |  | ||||||
|  | @ -37,7 +37,7 @@ namespace UserspaceEmulator { | ||||||
| 
 | 
 | ||||||
| class Emulator { | class Emulator { | ||||||
| public: | public: | ||||||
|     explicit Emulator(NonnullRefPtr<ELF::Loader>); |     Emulator(const String& executable_path, NonnullRefPtr<ELF::Loader>); | ||||||
| 
 | 
 | ||||||
|     bool load_elf(); |     bool load_elf(); | ||||||
|     void dump_backtrace(); |     void dump_backtrace(); | ||||||
|  | @ -63,6 +63,8 @@ private: | ||||||
| 
 | 
 | ||||||
|     bool m_shutdown { false }; |     bool m_shutdown { false }; | ||||||
|     int m_exit_status { 0 }; |     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); |     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) | void SoftCPU::push32(u32 value) | ||||||
| { | { | ||||||
|     set_esp(esp() - sizeof(value)); |     set_esp(esp() - sizeof(value)); | ||||||
|  |  | ||||||
|  | @ -75,6 +75,8 @@ public: | ||||||
|     void push32(u32); |     void push32(u32); | ||||||
|     u32 pop32(); |     u32 pop32(); | ||||||
| 
 | 
 | ||||||
|  |     void push_string(const StringView&); | ||||||
|  | 
 | ||||||
|     u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; } |     u16 segment(X86::SegmentRegister seg) const { return m_segment[(int)seg]; } | ||||||
|     u16& segment(X86::SegmentRegister seg) { 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()); |     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()) |     if (!emulator.load_elf()) | ||||||
|         return 1; |         return 1; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling