From: l4check Date: Wed, 23 Jun 2010 08:50:53 +0000 (+0000) Subject: update X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/commitdiff_plain/ccc535bec212362f3a59396690b260f36f9ea9c5 update git-svn-id: http://svn.tudos.org/repos/oc/tudos/trunk@8 d050ee49-bd90-4346-b210-929a50b99cfc --- diff --git a/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp b/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp index 058e0fc72..77f8b6f44 100644 --- a/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp +++ b/kernel/fiasco/src/kern/ia32/32/thread-ia32-32.cpp @@ -19,7 +19,7 @@ Thread::fast_return_to_user(Mword ip, Mword sp, bool = true) } IMPLEMENT inline -Mword +Mword Thread::user_sp() const { return regs()->sp(); } @@ -102,7 +102,7 @@ Thread::copy_utcb_to_ts(L4_msg_tag const &tag, Thread *snd, Thread *rcv, if (EXPECT_FALSE(rcv->exception_triggered())) { // triggered exception pending - Mem::memcpy_mwords (&ts->_gs, snd_utcb->values, s > 12 ? 12 : s); + Mem::memcpy_mwords(&ts->_gs, snd_utcb->values, s > 12 ? 12 : s); if (EXPECT_TRUE(s > 15)) { Continuation::User_return_frame const *s @@ -178,57 +178,57 @@ Thread::user_ip(Mword ip) PRIVATE inline int -Thread::check_trap13_kernel (Trap_state *ts) +Thread::check_trap13_kernel(Trap_state *ts) { - if (EXPECT_FALSE (ts->_trapno == 13 && (ts->_err & 3) == 0)) + if (EXPECT_FALSE(ts->_trapno == 13 && (ts->_err & 3) == 0)) { // First check if user loaded a segment register with 0 because the // resulting exception #13 can be raised from user _and_ kernel. If // the user tried to load another segment selector, the thread gets // killed. // XXX Should we emulate this too? Michael Hohmuth: Yes, we should. - if (EXPECT_FALSE (!(ts->_ds & 0xffff))) + if (EXPECT_FALSE(!(ts->_ds & 0xffff))) { - Cpu::set_ds (Gdt::data_segment ()); + Cpu::set_ds(Gdt::data_segment()); return 0; } - if (EXPECT_FALSE (!(ts->_es & 0xffff))) + if (EXPECT_FALSE(!(ts->_es & 0xffff))) { - Cpu::set_es (Gdt::data_segment ()); + Cpu::set_es(Gdt::data_segment()); return 0; } - if (EXPECT_FALSE (!(ts->_fs & 0xffff))) + if (EXPECT_FALSE(!(ts->_fs & 0xffff))) { ts->_fs = Utcb_init::utcb_segment(); return 0; } - if (EXPECT_FALSE (!(ts->_gs & 0xffff))) + if (EXPECT_FALSE(!(ts->_gs & 0xffff))) { ts->_gs = Utcb_init::utcb_segment(); return 0; } - if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user) + if (EXPECT_FALSE(ts->_ds & 0xfff8) == Gdt::gdt_code_user) { WARN("%p eip=%08lx: code selector ds=%04lx", this, ts->ip(), ts->_ds & 0xffff); - Cpu::set_ds (Gdt::data_segment ()); + Cpu::set_ds(Gdt::data_segment()); return 0; } - if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user) + if (EXPECT_FALSE(ts->_es & 0xfff8) == Gdt::gdt_code_user) { WARN("%p eip=%08lx: code selector es=%04lx", this, ts->ip(), ts->_es & 0xffff); - Cpu::set_es (Gdt::data_segment ()); + Cpu::set_es(Gdt::data_segment()); return 0; } - if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user) + if (EXPECT_FALSE(ts->_fs & 0xfff8) == Gdt::gdt_code_user) { WARN("%p eip=%08lx: code selector fs=%04lx", this, ts->ip(), ts->_fs & 0xffff); ts->_fs = Utcb_init::utcb_segment(); return 0; } - if (EXPECT_FALSE (ts->_ds & 0xfff8) == Gdt::gdt_code_user) + if (EXPECT_FALSE(ts->_gs & 0xfff8) == Gdt::gdt_code_user) { WARN("%p eip=%08lx: code selector gs=%04lx", this, ts->ip(), ts->_gs & 0xffff); diff --git a/kernel/fiasco/src/kern/ia32/thread-ia32.cpp b/kernel/fiasco/src/kern/ia32/thread-ia32.cpp index 9a5428a07..3066221ef 100644 --- a/kernel/fiasco/src/kern/ia32/thread-ia32.cpp +++ b/kernel/fiasco/src/kern/ia32/thread-ia32.cpp @@ -103,7 +103,7 @@ Thread::user_flags() const PRIVATE inline int -Thread::is_privileged_for_debug (Trap_state * /*ts*/) +Thread::is_privileged_for_debug(Trap_state * /*ts*/) { #if 0 return ((ts->flags() & EFLAGS_IOPL) == EFLAGS_IOPL_U); @@ -126,7 +126,7 @@ Thread::is_privileged_for_debug (Trap_state * /*ts*/) @param ip pagefault address */ IMPLEMENT inline bool -Thread::pagein_tcb_request (Return_frame *regs) +Thread::pagein_tcb_request(Return_frame *regs) { unsigned long new_ip = regs->ip(); if (*(Unsigned8*)new_ip == 0x48) // REX.W @@ -195,7 +195,7 @@ Thread::print_page_fault_error(Mword e) */ PUBLIC int -Thread::handle_slow_trap (Trap_state *ts) +Thread::handle_slow_trap(Trap_state *ts) { Address ip; int from_user = ts->cs() & 3; @@ -230,7 +230,7 @@ Thread::handle_slow_trap (Trap_state *ts) if (!check_trap13_kernel (ts)) return 0; - if (EXPECT_FALSE (!from_user)) + if (EXPECT_FALSE(!from_user)) { // get also here if a pagefault was not handled by the user level pager if (ts->_trapno == 14) @@ -239,13 +239,13 @@ Thread::handle_slow_trap (Trap_state *ts) goto generic_debug; // we were in kernel mode -- nothing to emulate } - if (EXPECT_FALSE (ts->_trapno == 2)) + if (EXPECT_FALSE(ts->_trapno == 2)) goto generic_debug; // NMI always enters kernel debugger - if (EXPECT_FALSE (ts->_trapno == 0xffffffff)) + if (EXPECT_FALSE(ts->_trapno == 0xffffffff)) goto generic_debug; // debugger interrupt - check_f00f_bug (ts); + check_f00f_bug(ts); // so we were in user mode -- look for something to emulate @@ -267,7 +267,7 @@ Thread::handle_slow_trap (Trap_state *ts) _recover_jmpbuf = &pf_recovery; - switch (handle_io_page_fault (ts, from_user)) + switch (handle_io_page_fault(ts, from_user)) { case 1: goto success; case 2: goto fail; @@ -290,7 +290,7 @@ Thread::handle_slow_trap (Trap_state *ts) } // just print out some warning, we do the normal exception handling - handle_sysenter_trap (ts, ip, from_user); + handle_sysenter_trap(ts, ip, from_user); // check for general protection exception if (ts->_trapno == 13 && (ts->_err & 0xffff) == 0) @@ -330,7 +330,7 @@ Thread::handle_slow_trap (Trap_state *ts) if (EXPECT_FALSE (is_privileged && (ip < Kmem::mem_user_max - 2) - && (mem_space()->peek ((Unsigned16*) ip, from_user)) == 0x300f + && (mem_space()->peek((Unsigned16*) ip, from_user)) == 0x300f && (Cpu::cpus.cpu(cpu()).can_wrmsr()))) { printf("Detected wrmsr at %lx\n", ip); @@ -349,13 +349,13 @@ Thread::handle_slow_trap (Trap_state *ts) if (EXPECT_FALSE (is_privileged && (ip < Kmem::mem_user_max - 2) - && (mem_space()->peek ((Unsigned16*) ip, from_user)) == 0x320f + && (mem_space()->peek((Unsigned16*) ip, from_user)) == 0x320f && (Cpu::cpus.cpu(cpu()).can_wrmsr()))) { printf("Detected rdmsr at %lx\n", ip); if (0) { - do_rdmsr_in_kernel (ts); + do_rdmsr_in_kernel(ts); // consume instruction and continue ts->consume_instruction(2); @@ -375,7 +375,7 @@ check_exception: // let's see if we have a trampoline to invoke if (ts->_trapno < 0x20 && ts->_trapno < _idt_limit) { - Idt_entry e = mem_space()->peek (_idt + ts->_trapno, 1); + Idt_entry e = mem_space()->peek(_idt + ts->_trapno, 1); if ((e.ist() & 0xe0) == 0x00 && (e.access() & 0x1f) == 0x0f) // gate descriptor ok? @@ -392,7 +392,7 @@ check_exception: { // someone interfered and changed our state assert (state() & Thread_cancel); - state_del (Thread_cancel); + state_del(Thread_cancel); } goto success; // we've consumed the trap @@ -402,7 +402,7 @@ check_exception: // backward compatibility cruft: check for those insane "int3" debug // messaging command sequences - if (ts->_trapno == 3 && is_privileged_for_debug (ts)) + if (ts->_trapno == 3 && is_privileged_for_debug(ts)) { if (int3_handler && int3_handler(ts)) goto success; @@ -427,7 +427,7 @@ fail_nomsg: ts->dump(); if (Config::conservative) - kdb_ke ("thread killed"); + kdb_ke("thread killed"); halt(); @@ -439,9 +439,9 @@ generic_debug: _recover_jmpbuf = 0; if (!nested_trap_handler) - return handle_not_nested_trap (ts); + return handle_not_nested_trap(ts); - return call_nested_trap_handler (ts); + return call_nested_trap_handler(ts); } /** @@ -455,8 +455,8 @@ generic_debug: */ extern "C" FIASCO_FASTCALL int -thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags, - Return_frame *regs) +thread_page_fault(Address pfa, Mword error_code, Address ip, Mword flags, + Return_frame *regs) { // XXX: need to do in a different way, if on debug stack e.g. @@ -481,7 +481,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags, else { // page fault in kernel memory region - if (Kmem::is_kmem_page_fault (pfa, error_code)) + if (Kmem::is_kmem_page_fault(pfa, error_code)) { // We've interrupted a context in the kernel with disabled interrupts, // the page fault address is in the kernel region, the error code is @@ -491,7 +491,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags, // Remain cli'd !!! } else if (!Config::conservative && - !Kmem::is_kmem_page_fault (pfa, error_code)) + !Kmem::is_kmem_page_fault(pfa, error_code)) { // No error -- just enable interrupts. Proc::sti(); @@ -506,7 +506,7 @@ thread_page_fault (Address pfa, Mword error_code, Address ip, Mword flags, } } - return current_thread()->handle_page_fault (pfa, error_code, ip, regs); + return current_thread()->handle_page_fault(pfa, error_code, ip, regs); } /** The catch-all trap entry point. Called by assembly code when a @@ -530,7 +530,7 @@ thread_handle_trap(Trap_state *ts, unsigned) IMPLEMENT inline bool -Thread::handle_sigma0_page_fault (Address pfa) +Thread::handle_sigma0_page_fault(Address pfa) { size_t size; @@ -636,7 +636,7 @@ IMPLEMENTATION [(ia32,amd64,ux) && !io]: PRIVATE inline int -Thread::handle_io_page_fault (Trap_state *, bool) +Thread::handle_io_page_fault(Trap_state *, bool) { return 0; } PRIVATE inline @@ -669,7 +669,7 @@ static void int3_handler_init() { - Thread::set_int3_handler (Thread::handle_int3); + Thread::set_int3_handler(Thread::handle_int3); } IMPLEMENT static inline NEEDS ["gdt.h"] @@ -737,7 +737,7 @@ Thread::set_int3_handler(int (*handler)(Trap_state *ts)) */ PUBLIC static int -Thread::handle_int3 (Trap_state *ts) +Thread::handle_int3(Trap_state *ts) { Mem_space *s = current_mem_space(); int from_user = ts->cs() & 3; @@ -854,7 +854,7 @@ Thread::handle_int3 (Trap_state *ts) PRIVATE inline void -Thread::check_f00f_bug (Trap_state *ts) +Thread::check_f00f_bug(Trap_state *ts) { // If we page fault on the IDT, it must be because of the F00F bug. // Figure out exception slot and raise the corresponding exception. @@ -879,9 +879,8 @@ Thread::check_io_bitmap_delimiter_fault(Trap_state *ts) // page fault in the first byte following the IO bitmap // map in the cpu_page read_only at the place Mem_space::Status result = - mem_space()->v_insert ( - Mem_space::Phys_addr(mem_space()->virt_to_phys_s0 - ((void*)Kmem::io_bitmap_delimiter_page())), + mem_space()->v_insert( + Mem_space::Phys_addr(mem_space()->virt_to_phys_s0((void*)Kmem::io_bitmap_delimiter_page())), Mem_space::Addr::create(Mem_layout::Io_bitmap + Mem_layout::Io_port_max / 8), Mem_space::Size::create(Config::PAGE_SIZE), Pt_entry::global()); @@ -907,25 +906,25 @@ Thread::check_io_bitmap_delimiter_fault(Trap_state *ts) PRIVATE inline bool -Thread::handle_sysenter_trap (Trap_state *ts, Address eip, bool from_user) +Thread::handle_sysenter_trap(Trap_state *ts, Address eip, bool from_user) { if (EXPECT_FALSE ((ts->_trapno == 6 || ts->_trapno == 13) && (ts->_err & 0xffff) == 0 && (eip < Kmem::mem_user_max - 2) - && (mem_space()->peek ((Unsigned16*) eip, from_user)) == 0x340f)) + && (mem_space()->peek((Unsigned16*) eip, from_user)) == 0x340f)) { // somebody tried to do sysenter on a machine without support for it - WARN ("tcb=%p killed:\n" - "\033[1;31mSYSENTER not supported on this machine\033[0m", - this); + WARN("tcb=%p killed:\n" + "\033[1;31mSYSENTER not supported on this machine\033[0m", + this); if (Cpu::have_sysenter()) // GP exception if sysenter is not correctly set up.. - WARN ("MSR_SYSENTER_CS: %llx", Cpu::rdmsr (MSR_SYSENTER_CS)); + WARN("MSR_SYSENTER_CS: %llx", Cpu::rdmsr(MSR_SYSENTER_CS)); else // We get UD exception on processors without SYSENTER/SYSEXIT. - WARN ("SYSENTER/EXIT not available."); + WARN("SYSENTER/EXIT not available."); return false; } @@ -935,12 +934,12 @@ Thread::handle_sysenter_trap (Trap_state *ts, Address eip, bool from_user) PRIVATE inline bool -Thread::trap_is_privileged (Trap_state *) +Thread::trap_is_privileged(Trap_state *) { return space()->has_io_privileges(); } PRIVATE inline void -Thread::do_wrmsr_in_kernel (Trap_state *ts) +Thread::do_wrmsr_in_kernel(Trap_state *ts) { // do "wrmsr (msr[ecx], edx:eax)" in kernel Cpu::wrmsr (ts->value(), ts->value3(), ts->value2()); @@ -948,26 +947,26 @@ Thread::do_wrmsr_in_kernel (Trap_state *ts) PRIVATE inline void -Thread::do_rdmsr_in_kernel (Trap_state *ts) +Thread::do_rdmsr_in_kernel(Trap_state *ts) { // do "rdmsr (msr[ecx], edx:eax)" in kernel - Unsigned64 msr = Cpu::rdmsr (ts->value2()); + Unsigned64 msr = Cpu::rdmsr(ts->value2()); ts->value((Unsigned32) msr); ts->value3((Unsigned32) (msr >> 32)); } PRIVATE inline int -Thread::handle_not_nested_trap (Trap_state *ts) +Thread::handle_not_nested_trap(Trap_state *ts) { // no kernel debugger present - printf (" %p IP="L4_PTR_FMT" Trap=%02lx [Ret/Esc]\n", - this, ts->ip(), ts->_trapno); + printf(" %p IP="L4_PTR_FMT" Trap=%02lx [Ret/Esc]\n", + this, ts->ip(), ts->_trapno); int r; // cannot use normal getchar because it may block with hlt and irq's // are off here - while ((r=Kconsole::console()->getchar (false)) == -1) + while ((r=Kconsole::console()->getchar(false)) == -1) Proc::pause(); if (r == '\033') diff --git a/l4/Makefile b/l4/Makefile index f8eba633e..aab5e2c8b 100644 --- a/l4/Makefile +++ b/l4/Makefile @@ -336,6 +336,12 @@ qemu: SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \ $(L4DIR)/tool/bin/qemu-x86-launch $$ml "$$e" $(QEMU_OPTIONS) +kexec: + $(VERBOSE)$(entryselection); \ + L4DIR=$(L4DIR) \ + SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \ + $(L4DIR)/tool/bin/kexec-launch $$ml "$$e" + ux: $(VERBOSE)if [ "$(ARCH)" != "x86" ]; then \ echo "This mode can only be used with architecture x86."; \ @@ -373,7 +379,7 @@ grub2iso: SEARCHPATH="$(MODULE_SEARCH_PATH):$(BUILDDIR_SEARCHPATH)" \ $(L4DIR)/tool/bin/gengrub2iso --timeout=0 $$ml \ $(OBJ_BASE)/images/$$(echo $$e | tr '[ ]' '[_]').iso "$$e" - + .PHONY: image qemu ux switch_ram_base grub1iso grub2iso switch_ram_base: diff --git a/l4/pkg/bootstrap/server/src/ldscript.inc b/l4/pkg/bootstrap/server/src/ldscript.inc index a87fcb3b0..718fd5537 100644 --- a/l4/pkg/bootstrap/server/src/ldscript.inc +++ b/l4/pkg/bootstrap/server/src/ldscript.inc @@ -2,6 +2,7 @@ Common functionality for linker scripts in bootstrap */ #define CTORS \ + . = ALIGN(8); \ PROVIDE (__CTORS_BEGIN = .); \ KEEP (*(SORT(.ctors.*))) \ KEEP (*(.ctors)) \ diff --git a/l4/pkg/l4re/include/env.h b/l4/pkg/l4re/include/env.h index 6ca4ceed7..dbd061329 100644 --- a/l4/pkg/l4re/include/env.h +++ b/l4/pkg/l4re/include/env.h @@ -35,8 +35,9 @@ typedef struct l4re_env_cap_entry_t * \brief The capability selector for the obeject. */ l4_cap_idx_t cap; + /** - * \brief Some falgs for the object. + * \brief Some flags for the object. * \note Currently unused. */ l4_umword_t flags; diff --git a/l4/pkg/l4re_vfs/include/impl/ns_fs.h b/l4/pkg/l4re_vfs/include/impl/ns_fs.h index 0f6d9e935..b288ac8be 100644 --- a/l4/pkg/l4re_vfs/include/impl/ns_fs.h +++ b/l4/pkg/l4re_vfs/include/impl/ns_fs.h @@ -39,14 +39,16 @@ protected: class Env_dir : public Ns_base_dir { public: - explicit Env_dir(L4Re::Env const *env) : _env(env) {} + explicit Env_dir(L4Re::Env const *env) + : _env(env), _current_cap_entry(env->initial_caps()) {} ssize_t readv(const struct iovec*, int) throw() { return -EISDIR; } ssize_t writev(const struct iovec*, int) throw() { return -EISDIR; } - int fstat64(struct stat64 *) const throw() { return -EINVAL; } + int fstat64(struct stat64 *) const throw(); int faccessat(const char *path, int mode, int flags) throw(); int get_entry(const char *path, int flags, mode_t mode, Ref_ptr *) throw(); + ssize_t getdents(char *, size_t) throw(); ~Env_dir() throw() {} @@ -55,7 +57,7 @@ private: int get_ds(const char *path, L4Re::Auto_cap::Cap *ds) throw(); L4Re::Env const *_env; - + Env::Cap_entry const *_current_cap_entry; }; class Ns_dir : public Ns_base_dir @@ -65,7 +67,7 @@ public: ssize_t readv(const struct iovec*, int) throw() { return -EISDIR; } ssize_t writev(const struct iovec*, int) throw() { return -EISDIR; } - int fstat64(struct stat64 *) const throw() { return -EINVAL; } + int fstat64(struct stat64 *) const throw(); int faccessat(const char *path, int mode, int flags) throw(); int get_entry(const char *path, int flags, mode_t mode, Ref_ptr *) throw(); diff --git a/l4/pkg/l4re_vfs/include/impl/ns_fs_impl.h b/l4/pkg/l4re_vfs/include/impl/ns_fs_impl.h index 7482ad96c..8cb099244 100644 --- a/l4/pkg/l4re_vfs/include/impl/ns_fs_impl.h +++ b/l4/pkg/l4re_vfs/include/impl/ns_fs_impl.h @@ -19,7 +19,7 @@ #include #include -#include +#include namespace L4Re { namespace Core { @@ -112,6 +112,25 @@ Ns_dir::faccessat(const char *path, int mode, int flags) throw() return 0; } +int Ns_dir:: +fstat64(struct stat64 *b) const throw() +{ + b->st_dev = 1; + b->st_ino = 1; + b->st_mode = S_IRWXU | S_IFDIR; + b->st_nlink = 0; + b->st_uid = 0; + b->st_gid = 0; + b->st_rdev = 0; + b->st_size = 0; + b->st_blksize = 0; + b->st_blocks = 0; + b->st_atime = 0; + b->st_mtime = 0; + b->st_ctime = 0; + return 0; +} + int Env_dir::get_ds(const char *path, L4Re::Auto_cap::Cap *ds) throw() { @@ -221,4 +240,62 @@ Env_dir::faccessat(const char *path, int mode, int flags) throw() return 0; } +int +Env_dir::fstat64(struct stat64 *b) const throw() +{ + b->st_dev = 1; + b->st_ino = 1; + b->st_mode = S_IRWXU | S_IFDIR; + b->st_nlink = 0; + b->st_uid = 0; + b->st_gid = 0; + b->st_rdev = 0; + b->st_size = 0; + b->st_blksize = 0; + b->st_blocks = 0; + b->st_atime = 0; + b->st_mtime = 0; + b->st_ctime = 0; + return 0; +} + +ssize_t +Env_dir::getdents(char *buf, size_t sz) throw() +{ + struct dirent64 *d = (struct dirent64 *)buf; + ssize_t ret = 0; + + while (d + && _current_cap_entry + && _current_cap_entry->flags != ~0UL) + { + unsigned l = strlen(_current_cap_entry->name) + 1; + if (l > sizeof(d->d_name)) + l = sizeof(d->d_name); + + unsigned n = offsetof (struct dirent64, d_name) + l; + + if (n <= sz) + { + d->d_ino = 1; + d->d_off = 0; + memcpy(d->d_name, _current_cap_entry->name, l); + d->d_name[l - 1] = 0; + d->d_reclen = n; + ret += n; + sz -= n; + d = (struct dirent64 *)((unsigned long)d + n); + _current_cap_entry++; + } + else + return ret; + } + + // bit of a hack because we should only (re)set this when opening the dir + if (!ret) + _current_cap_entry = _env->initial_caps(); + + return ret; +} + }} diff --git a/l4/pkg/l4re_vfs/include/impl/ro_file.h b/l4/pkg/l4re_vfs/include/impl/ro_file.h index d6e05f7a9..b5ff4841a 100644 --- a/l4/pkg/l4re_vfs/include/impl/ro_file.h +++ b/l4/pkg/l4re_vfs/include/impl/ro_file.h @@ -44,6 +44,8 @@ public: off64_t lseek64(off64_t, int) throw(); int fstat64(struct stat64 *buf) const throw(); + int ioctl(unsigned long, va_list) throw(); + int get_status_flags() const throw() { return O_RDONLY; } diff --git a/l4/pkg/l4re_vfs/include/impl/ro_file_impl.h b/l4/pkg/l4re_vfs/include/impl/ro_file_impl.h index 7f900174f..0804ea2d3 100644 --- a/l4/pkg/l4re_vfs/include/impl/ro_file_impl.h +++ b/l4/pkg/l4re_vfs/include/impl/ro_file_impl.h @@ -17,6 +17,8 @@ #include "ds_util.h" #include "ro_file.h" +#include + #include namespace L4Re { namespace Core { @@ -139,4 +141,17 @@ Ro_file::lseek64(off64_t offset, int whence) throw() return _f_pos; } +int +Ro_file::ioctl(unsigned long v, va_list args) throw() +{ + switch (v) + { + case FIONREAD: // return amount of data still available + int *available = va_arg(args, int *); + *available = _size - _f_pos; + return 0; + }; + return -EINVAL; +} + }} diff --git a/l4/pkg/tmpfs/lib/src/fs.cc b/l4/pkg/tmpfs/lib/src/fs.cc index f3c5ae33c..efeca5bf2 100644 --- a/l4/pkg/tmpfs/lib/src/fs.cc +++ b/l4/pkg/tmpfs/lib/src/fs.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -177,6 +178,7 @@ public: ssize_t writev(const struct iovec*, int iovcnt) throw(); off64_t lseek64(off64_t, int) throw(); int fstat64(struct stat64 *buf) const throw(); + int ioctl(unsigned long, va_list) throw(); private: Ref_ptr _file; @@ -218,7 +220,6 @@ int Tmpfs_file::fstat64(struct stat64 *buf) const throw() return 0; } - off64_t Tmpfs_file::lseek64(off64_t offset, int whence) throw() { switch (whence) @@ -235,6 +236,21 @@ off64_t Tmpfs_file::lseek64(off64_t offset, int whence) throw() return _pos; } +int +Tmpfs_file::ioctl(unsigned long v, va_list args) throw() +{ + switch (v) + { + case FIONREAD: // return amount of data still available + int *available = va_arg(args, int *); + *available = _file->data().size() - _pos; + return 0; + }; + return -EINVAL; +} + + + int Tmpfs_dir::get_entry(const char *name, int flags, mode_t mode, diff --git a/l4/tool/bin/qemu-x86-launch b/l4/tool/bin/qemu-x86-launch index 2376e3b27..5cc1c20bc 100755 --- a/l4/tool/bin/qemu-x86-launch +++ b/l4/tool/bin/qemu-x86-launch @@ -28,23 +28,10 @@ sub get_file($$) my $command = shift; my $cmdline = shift; - my $fp = L4::ModList::search_file_or_die($command, $module_path); + my $fp = L4::ModList::get_file_uncompressed_or_die($command, $module_path, + $unzip_tmp); $cmdline =~ s/^\S+\s*//; - - open F, $fp || die "connot open '$fp': $!"; - my $buf; - read F, $buf, 2; - close F; - - if (unpack("n", $buf) == 0x1f8b) { - (my $tf = $fp) =~ s|.*/||; - $tf = $unzip_tmp.'/'.$tf; - print "'$fp' is a zipped file, uncompressing to '$tf'\n"; - system("zcat $fp >$tf"); - $fp = $tf; - } - $fp.' '.$cmdline; } diff --git a/l4/tool/lib/L4/ModList.pm b/l4/tool/lib/L4/ModList.pm index 8053c66b4..928d32a65 100644 --- a/l4/tool/lib/L4/ModList.pm +++ b/l4/tool/lib/L4/ModList.pm @@ -272,6 +272,33 @@ sub search_file_or_die($$) $f; } +sub get_file_uncompressed_or_die($$$) +{ + my $command = shift; + my $paths = shift; + my $tmpdir = shift; + + my $fp = L4::ModList::search_file_or_die($command, $paths); + + open F, $fp || die "connot open '$fp': $!"; + my $buf; + read F, $buf, 2; + close F; + + if (unpack("n", $buf) == 0x1f8b) { + (my $tf = $fp) =~ s|.*/||; + $tf = $tmpdir.'/'.$tf; + print "'$fp' is a zipped file, uncompressing to '$tf'\n"; + system("zcat $fp >$tf"); + $fp = $tf; + } + + $fp; +} + + + + sub generate_grub1_entry($$%) { my $entryname = shift;