Changeset 04803bf in mainline for uspace/srv/loader
- Timestamp:
- 2011-03-21T22:00:17Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 143932e3
- Parents:
- b50b5af2 (diff), 7308e84 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- uspace/srv/loader
- Files:
-
- 3 added
- 22 edited
-
Makefile (modified) (3 diffs)
-
arch/abs32le/Makefile.inc (added)
-
arch/abs32le/_link.ld.in (added)
-
arch/abs32le/abs32le.c (added)
-
arch/amd64/Makefile.inc (modified) (1 diff)
-
arch/amd64/_link.ld.in (modified) (7 diffs)
-
arch/arm32/Makefile.inc (modified) (1 diff)
-
arch/arm32/_link.ld.in (modified) (5 diffs)
-
arch/arm32/arm32.s (modified) (1 diff)
-
arch/ia32/Makefile.inc (modified) (1 diff)
-
arch/ia32/_link.ld.in (modified) (5 diffs)
-
arch/ia32/ia32.s (modified) (1 diff)
-
arch/ia64/Makefile.inc (modified) (1 diff)
-
arch/ia64/_link.ld.in (modified) (5 diffs)
-
arch/mips32/Makefile.inc (modified) (1 diff)
-
arch/mips32/_link.ld.in (modified) (5 diffs)
-
arch/ppc32/Makefile.inc (modified) (1 diff)
-
arch/ppc32/_link.ld.in (modified) (6 diffs)
-
arch/sparc64/Makefile.inc (modified) (1 diff)
-
arch/sparc64/_link.ld.in (modified) (4 diffs)
-
elf_load.c (modified) (10 diffs)
-
include/arch.h (modified) (1 diff)
-
include/elf.h (modified) (1 diff)
-
include/elf_load.h (modified) (3 diffs)
-
main.c (modified) (18 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/loader/Makefile
rb50b5af2 r04803bf 1 1 # 2 2 # Copyright (c) 2005 Martin Decky 3 # Copyright (c) 200 8 Jiri Svoboda3 # Copyright (c) 2007 Jakub Jermar 4 4 # All rights reserved. 5 5 # … … 28 28 # 29 29 30 ## Setup toolchain 31 # 30 USPACE_PREFIX = ../.. 31 ROOT_PATH = $(USPACE_PREFIX)/.. 32 32 33 LIBC_PREFIX = ../../lib/libc 34 SOFTINT_PREFIX = ../../lib/softint 33 COMMON_MAKEFILE = $(ROOT_PATH)/Makefile.common 34 CONFIG_MAKEFILE = $(ROOT_PATH)/Makefile.config 35 35 36 include $(LIBC_PREFIX)/Makefile.toolchain 37 include arch/$(UARCH)/Makefile.inc 36 -include $(COMMON_MAKEFILE) 37 -include $(CONFIG_MAKEFILE) 38 -include arch/$(UARCH)/Makefile.inc 38 39 39 CFLAGS += -Iinclude 40 LINKER_SCRIPT = arch/$(UARCH)/_link.ld 41 EXTRA_CLEAN = $(LINKER_SCRIPT) 40 42 41 LIBS = $(LIBC_PREFIX)/libc.a $(SOFTINT_PREFIX)/libsoftint.a 43 EXTRA_CFLAGS = -Iinclude 42 44 43 ## Sources 44 # 45 BINARY = loader 45 46 46 OUTPUT = loader47 47 GENERIC_SOURCES = \ 48 48 main.c \ … … 50 50 interp.s 51 51 52 SOURCES := $(GENERIC_SOURCES) $(ARCH_SOURCES) 53 OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) 52 SOURCES = \ 53 $(GENERIC_SOURCES) \ 54 $(ARCH_SOURCES) 54 55 55 .PHONY: all clean depend disasm 56 include $(USPACE_PREFIX)/Makefile.common 56 57 57 all: $(OUTPUT) disasm 58 59 -include Makefile.depend 60 61 clean: 62 -rm -f $(OUTPUT) $(OBJECTS) $(OUTPUT).map $(OUTPUT).disasm arch/$(UARCH)/_link.ld Makefile.depend 63 64 depend: 65 $(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend 66 67 $(OUTPUT): $(OBJECTS) $(LIBS) arch/$(UARCH)/_link.ld 68 $(LD) -T arch/$(UARCH)/_link.ld $(LFLAGS) $(OBJECTS) $(LIBS) -o $@ -Map $(OUTPUT).map 69 70 disasm: 71 $(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm 72 73 arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in 74 $(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ 75 76 %.o: %.S 77 $(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ 78 79 %.o: %.s 80 $(AS) $(AFLAGS) $< -o $@ 81 82 %.o: %.c 83 $(CC) $(DEFS) $(CFLAGS) -c $< -o $@ 58 $(LINKER_SCRIPT): $(LINKER_SCRIPT).in 59 $(GCC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ -
uspace/srv/loader/arch/amd64/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__64_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/amd64.s 29 ARCH_SOURCES = arch/$(UARCH)/amd64.s -
uspace/srv/loader/arch/amd64/_link.ld.in
rb50b5af2 r04803bf 1 /* 2 * The difference from _link.ld.in for regular statically-linked apps 3 * is the base address and the special interp section. 4 */ 5 1 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 2 7 ENTRY(__entry) … … 6 11 text PT_LOAD FLAGS(5); 7 12 data PT_LOAD FLAGS(6); 13 debug PT_NOTE; 8 14 } 9 15 … … 11 17 .interp : { 12 18 *(.interp); 13 } : interp14 15 /* . = 0x0000700000001000; */19 } :interp 20 21 /* . = 0x0000700000001000; */ 16 22 . = 0x70001000; 17 23 … … 19 25 *(.init); 20 26 } :text 27 21 28 .text : { 22 29 *(.text); … … 27 34 *(.data); 28 35 } :data 36 29 37 .tdata : { 30 38 _tdata_start = .; … … 32 40 _tdata_end = .; 33 41 } :data 42 34 43 .tbss : { 35 44 _tbss_start = .; … … 37 46 _tbss_end = .; 38 47 } :data 48 39 49 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 40 51 .bss : { 41 52 *(COMMON); 42 53 *(.bss); 43 54 } :data 44 45 . = ALIGN(0x1000); 46 _heap = .; 55 56 #ifdef CONFIG_LINE_DEBUG 57 .comment 0 : { *(.comment); } :debug 58 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 59 .debug_aranges 0 : { *(.debug_aranges); } :debug 60 .debug_info 0 : { *(.debug_info); } :debug 61 .debug_line 0 : { *(.debug_line); } :debug 62 .debug_loc 0 : { *(.debug_loc); } :debug 63 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 64 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 65 .debug_ranges 0 : { *(.debug_ranges); } :debug 66 .debug_str 0 : { *(.debug_str); } :debug 67 #endif 47 68 48 69 /DISCARD/ : { 49 70 *(*); 50 71 } 51 52 72 } -
uspace/srv/loader/arch/arm32/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__32_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/arm32.s 29 ARCH_SOURCES = arch/$(UARCH)/arm32.s -
uspace/srv/loader/arch/arm32/_link.ld.in
rb50b5af2 r04803bf 3 3 * is the base address. 4 4 */ 5 5 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 6 7 ENTRY(__entry) … … 16 17 *(.interp); 17 18 } : interp 18 19 19 20 . = 0x70001000; 20 21 21 22 .init ALIGN(0x1000): SUBALIGN(0x1000) { 22 23 *(.init); 23 } : text 24 } :text 25 24 26 .text : { 25 27 *(.text); 26 *(.rodata*);28 *(.rodata*); 27 29 } :text 28 30 … … 32 34 *(.sdata); 33 35 } :data 36 34 37 .tdata : { 35 38 _tdata_start = .; … … 37 40 _tdata_end = .; 38 41 } :data 42 39 43 .tbss : { 40 44 _tbss_start = .; … … 42 46 _tbss_end = .; 43 47 } :data 48 44 49 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 45 51 .bss : { 46 52 *(.sbss); 47 53 *(.scommon); 48 *(COMMON);49 *(.bss);54 *(COMMON); 55 *(.bss); 50 56 } :data 51 52 . = ALIGN(0x1000);53 _heap = .;54 57 55 58 /DISCARD/ : { 56 59 *(*); 57 60 } 58 59 61 } -
uspace/srv/loader/arch/arm32/arm32.s
rb50b5af2 r04803bf 36 36 # Jump to a program entry point 37 37 program_run: 38 # load ras_page address to r2 39 ldr r2, =ras_page 40 ldr r2, [r2] 38 41 # pcb is passed to the entry point in r1 (where it already is) 39 42 mov r15, r0 -
uspace/srv/loader/arch/ia32/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__32_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/ia32.s 29 ARCH_SOURCES = arch/$(UARCH)/ia32.s -
uspace/srv/loader/arch/ia32/_link.ld.in
rb50b5af2 r04803bf 3 3 * is the base address and the special interp section. 4 4 */ 5 5 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 6 7 ENTRY(__entry) … … 8 9 PHDRS { 9 10 interp PT_INTERP; 10 text PT_LOAD FILEHDR PHDRS FLAGS(5);11 text PT_LOAD FILEHDR PHDRS FLAGS(5); 11 12 data PT_LOAD FLAGS(6); 13 debug PT_NOTE; 12 14 } 13 15 … … 16 18 *(.interp); 17 19 } :interp 18 20 19 21 . = 0x70001000; 20 22 21 23 .init ALIGN(0x1000) : SUBALIGN(0x1000) { 22 24 *(.init); 23 25 } :text 26 24 27 .text : { 25 28 *(.text); 26 *(.rodata*);29 *(.rodata*); 27 30 } :text 28 31 … … 30 33 *(.data); 31 34 } :data 35 32 36 .tdata : { 33 37 _tdata_start = .; 34 38 *(.tdata); 39 *(.gnu.linkonce.tb.*); 35 40 _tdata_end = .; 36 41 } :data 42 37 43 .tbss : { 38 44 _tbss_start = .; … … 40 46 _tbss_end = .; 41 47 } :data 48 42 49 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 43 51 .bss : { 44 *(COMMON);45 *(.bss);52 *(COMMON); 53 *(.bss); 46 54 } :data 47 55 48 . = ALIGN(0x1000); 49 _heap = .; 56 #ifdef CONFIG_LINE_DEBUG 57 .comment 0 : { *(.comment); } :debug 58 .debug_abbrev 0 : { *(.debug_abbrev); } :debug 59 .debug_aranges 0 : { *(.debug_aranges); } :debug 60 .debug_info 0 : { *(.debug_info); } :debug 61 .debug_line 0 : { *(.debug_line); } :debug 62 .debug_loc 0 : { *(.debug_loc); } :debug 63 .debug_pubnames 0 : { *(.debug_pubnames); } :debug 64 .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug 65 .debug_ranges 0 : { *(.debug_ranges); } :debug 66 .debug_str 0 : { *(.debug_str); } :debug 67 #endif 50 68 51 69 /DISCARD/ : { 52 70 *(*); 53 71 } 54 55 72 } -
uspace/srv/loader/arch/ia32/ia32.s
rb50b5af2 r04803bf 40 40 movl 0x8(%ebp), %eax 41 41 42 # %e bx:= pcb43 # pcb is passed to the entry point in t %ebx44 mov 0xc(%ebp), %e bx42 # %edi := pcb 43 # pcb is passed to the entry point in %edi 44 mov 0xc(%ebp), %edi 45 45 46 46 # Save a tiny bit of stack space -
uspace/srv/loader/arch/ia64/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__64_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/ia64.s 29 ARCH_SOURCES = arch/$(UARCH)/ia64.s 31 30 AFLAGS += -xexplicit -
uspace/srv/loader/arch/ia64/_link.ld.in
rb50b5af2 r04803bf 12 12 *(.interp); 13 13 } :interp 14 14 15 15 /* On Itanium code sections must be aligned to 16 bytes. */ 16 16 . = ALIGN(0x800000000 + SIZEOF_HEADERS, 16); 17 17 18 18 .init : { 19 19 *(.init); 20 } : text 20 } :text 21 21 22 .text : { 22 23 *(.text); 23 24 *(.rodata*); 24 25 } :text 25 26 26 27 . = . + 0x4000; 27 28 28 29 .got : { 29 30 _gp = .; 30 31 *(.got*); 31 } :data 32 } :data 33 32 34 .data : { 33 35 *(.opd); … … 35 37 *(.sdata); 36 38 } :data 39 37 40 .tdata : { 38 41 _tdata_start = .; … … 40 43 _tdata_end = .; 41 44 } :data 45 42 46 .tbss : { 43 47 _tbss_start = .; … … 45 49 _tbss_end = .; 46 50 } :data 51 47 52 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 53 48 54 .bss : { 49 55 *(.sbss); … … 52 58 *(.bss); 53 59 } :data 54 55 . = ALIGN(0x4000); 56 _heap = .; 57 60 58 61 /DISCARD/ : { 59 62 *(*); 60 }63 } 61 64 } -
uspace/srv/loader/arch/mips32/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__32_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/mips32.s 29 ARCH_SOURCES = arch/$(UARCH)/mips32.s -
uspace/srv/loader/arch/mips32/_link.ld.in
rb50b5af2 r04803bf 3 3 * is the base address. 4 4 */ 5 5 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 6 7 ENTRY(__entry) … … 16 17 *(.interp); 17 18 } :interp 18 19 19 20 . = 0x70004000; 20 21 … … 22 23 *(.init); 23 24 } :text 25 24 26 .text : { 25 *(.text);27 *(.text); 26 28 *(.rodata*); 27 29 } :text 28 30 31 . = . + 0x4000; 32 29 33 .data : { 30 34 *(.data); 31 35 *(.data.rel*); 32 36 } :data 33 37 34 38 .got : { 35 39 _gp = .; 36 40 *(.got); 37 41 } :data 38 42 39 43 .tdata : { 40 44 _tdata_start = .; … … 42 46 _tdata_end = .; 43 47 } :data 48 44 49 .tbss : { 45 50 _tbss_start = .; … … 47 52 _tbss_end = .; 48 53 } :data 54 49 55 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 50 56 51 57 .sbss : { 52 58 *(.scommon); 53 59 *(.sbss); 54 } 60 } 61 55 62 .bss : { 56 63 *(.bss); 57 64 *(COMMON); 58 65 } :data 59 60 . = ALIGN(0x4000); 61 _heap = .; 62 66 63 67 /DISCARD/ : { 64 68 *(*); -
uspace/srv/loader/arch/ppc32/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__32_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/ppc32.s 29 ARCH_SOURCES = arch/$(UARCH)/ppc32.s -
uspace/srv/loader/arch/ppc32/_link.ld.in
rb50b5af2 r04803bf 3 3 * is the base address. 4 4 */ 5 5 6 STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) 6 7 ENTRY(__entry) … … 16 17 *(.interp); 17 18 } :interp 18 19 19 20 . = 0x70001000; 20 21 21 22 .init ALIGN(0x1000) : SUBALIGN(0x1000) { 22 23 *(.init); 23 24 } :text 25 24 26 .text : { 25 27 *(.text); … … 31 33 *(.sdata); 32 34 } :data 35 33 36 .tdata : { 34 37 _tdata_start = .; … … 36 39 _tdata_end = .; 37 40 } :data 41 38 42 .tbss : { 39 43 _tbss_start = .; … … 41 45 _tbss_end = .; 42 46 } :data 47 43 48 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 49 44 50 .bss : { 45 51 *(.sbss); … … 47 53 *(.bss); 48 54 } :data 49 50 . = ALIGN(0x1000);51 _heap = .;52 55 53 56 /DISCARD/ : { 54 57 *(*); 55 58 } 56 57 59 } -
uspace/srv/loader/arch/sparc64/Makefile.inc
rb50b5af2 r04803bf 27 27 # 28 28 29 CFLAGS += -D__64_BITS__ 30 ARCH_SOURCES := arch/$(UARCH)/sparc64.s 29 ARCH_SOURCES = arch/$(UARCH)/sparc64.s -
uspace/srv/loader/arch/sparc64/_link.ld.in
rb50b5af2 r04803bf 12 12 *(.interp); 13 13 } :interp 14 14 15 15 . = 0x70004000 + SIZEOF_HEADERS; 16 16 17 17 .init : { 18 18 *(.init); 19 19 } :text 20 20 21 .text : { 21 22 *(.text); 22 23 *(.rodata*); 23 24 } :text 24 25 25 26 . = . + 0x4000; 26 27 27 28 .got : { 28 29 _gp = .; 29 30 *(.got*); 30 31 } :data 32 31 33 .data : { 32 34 *(.data); 33 35 *(.sdata); 34 36 } :data 37 35 38 .tdata : { 36 39 _tdata_start = .; … … 38 41 _tdata_end = .; 39 42 } :data 43 40 44 .tbss : { 41 45 _tbss_start = .; … … 43 47 _tbss_end = .; 44 48 } :data 49 45 50 _tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); 51 46 52 .bss : { 47 53 *(.sbss); … … 49 55 *(.bss); 50 56 } :data 51 52 . = ALIGN(0x4000);53 _heap = .;54 57 55 58 /DISCARD/ : { 56 59 *(*); 57 60 } 58 59 61 } -
uspace/srv/loader/elf_load.c
rb50b5af2 r04803bf 60 60 #define DPRINTF(...) 61 61 62 static c har *error_codes[] = {62 static const char *error_codes[] = { 63 63 "no error", 64 64 "invalid image", … … 95 95 * pointed to by @a info. 96 96 * 97 * @param file_name Path to the ELF file.98 * @param so_bias Bias to use if the file is a shared object.99 * @param info Pointer to a structure for storing information100 * extracted from the binary.97 * @param file_name Path to the ELF file. 98 * @param so_bias Bias to use if the file is a shared object. 99 * @param info Pointer to a structure for storing information 100 * extracted from the binary. 101 101 * 102 102 * @return EOK on success or negative error code. 103 */ 104 int elf_load_file(char *file_name, size_t so_bias, eld_flags_t flags, 103 * 104 */ 105 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags, 105 106 elf_info_t *info) 106 107 { … … 109 110 int fd; 110 111 int rc; 111 112 112 113 fd = open(file_name, O_RDONLY); 113 114 if (fd < 0) { … … 269 270 * @return NULL terminated description of error. 270 271 */ 271 c har *elf_error(unsigned int rc)272 const char *elf_error(unsigned int rc) 272 273 { 273 274 assert(rc < sizeof(error_codes) / sizeof(char *)); … … 287 288 case PT_NULL: 288 289 case PT_PHDR: 290 case PT_NOTE: 289 291 break; 290 292 case PT_LOAD: … … 306 308 break; 307 309 case PT_SHLIB: 308 case PT_NOTE:309 310 // case PT_LOPROC: 310 311 // case PT_HIPROC: … … 340 341 seg_ptr = (void *) seg_addr; 341 342 342 DPRINTF("Load segment at addr 0x%x, size 0x%x\n",seg_addr,343 entry->p_memsz); 343 DPRINTF("Load segment at addr %p, size 0x%x\n", (void *) seg_addr, 344 entry->p_memsz); 344 345 345 346 if (entry->p_align > 1) { … … 368 369 mem_sz = entry->p_memsz + (entry->p_vaddr - base); 369 370 370 DPRINTF("Map to seg_addr=0x%x-0x%x.\n", seg_addr, 371 entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE)); 371 DPRINTF("Map to seg_addr=%p-%p.\n", (void *) seg_addr, 372 (void *) (entry->p_vaddr + bias + 373 ALIGN_UP(entry->p_memsz, PAGE_SIZE))); 372 374 373 375 /* … … 383 385 } 384 386 385 DPRINTF("as_area_create( 0x%lx, 0x%x, %d) -> 0x%lx\n",386 base + bias, mem_sz, flags, (uintptr_t)a);387 DPRINTF("as_area_create(%p, %#zx, %d) -> %p\n", 388 (void *) (base + bias), mem_sz, flags, (void *) a); 387 389 388 390 /* … … 464 466 break; 465 467 case SHT_DYNAMIC: 468 /* Record pointer to dynamic section into info structure */ 469 elf->info->dynamic = 470 (void *)((uint8_t *)entry->sh_addr + elf->bias); 471 DPRINTF("Dynamic section found at %p.\n", 472 (void *) elf->info->dynamic); 466 473 break; 467 474 default: -
uspace/srv/loader/include/arch.h
rb50b5af2 r04803bf 37 37 #define LOADER_ARCH_H_ 38 38 39 void program_run(void *entry_point, void *pcb);39 extern void program_run(void *entry_point, void *pcb); 40 40 41 41 #endif -
uspace/srv/loader/include/elf.h
rb50b5af2 r04803bf 337 337 #endif 338 338 339 extern c har *elf_error(unsigned int rc);339 extern const char *elf_error(unsigned int rc); 340 340 341 341 #endif -
uspace/srv/loader/include/elf_load.h
rb50b5af2 r04803bf 27 27 */ 28 28 29 /** @addtogroup generic 29 /** @addtogroup generic 30 30 * @{ 31 31 */ … … 56 56 57 57 /** ELF interpreter name or NULL if statically-linked */ 58 c har *interp;58 const char *interp; 59 59 60 60 /** Pointer to the dynamic section */ … … 82 82 } elf_ld_t; 83 83 84 int elf_load_file(c har *file_name, size_t so_bias, eld_flags_t flags,84 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags, 85 85 elf_info_t *info); 86 86 void elf_create_pcb(elf_info_t *info, pcb_t *pcb); -
uspace/srv/loader/main.c
rb50b5af2 r04803bf 50 50 #include <fcntl.h> 51 51 #include <sys/types.h> 52 #include <ipc/ipc.h>53 52 #include <ipc/services.h> 54 53 #include <ipc/loader.h> … … 58 57 #include <errno.h> 59 58 #include <async.h> 60 #include <str ing.h>59 #include <str.h> 61 60 #include <as.h> 62 61 … … 73 72 /** The Program control block */ 74 73 static pcb_t pcb; 74 75 /** Current working directory */ 76 static char *cwd = NULL; 75 77 76 78 /** Number of arguments */ … … 94 96 95 97 /** Used to limit number of connections to one. */ 96 static bool connected ;98 static bool connected = false; 97 99 98 100 static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request) … … 104 106 task_id = task_get_id(); 105 107 106 if (! ipc_data_read_receive(&callid, &len)) {107 ipc_answer_0(callid, EINVAL);108 ipc_answer_0(rid, EINVAL);108 if (!async_data_read_receive(&callid, &len)) { 109 async_answer_0(callid, EINVAL); 110 async_answer_0(rid, EINVAL); 109 111 return; 110 112 } … … 113 115 len = sizeof(task_id); 114 116 115 ipc_data_read_finalize(callid, &task_id, len); 116 ipc_answer_0(rid, EOK); 117 } 118 117 async_data_read_finalize(callid, &task_id, len); 118 async_answer_0(rid, EOK); 119 } 120 121 /** Receive a call setting the current working directory. 122 * 123 * @param rid 124 * @param request 125 */ 126 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request) 127 { 128 char *buf; 129 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 130 131 if (rc == EOK) { 132 if (cwd != NULL) 133 free(cwd); 134 135 cwd = buf; 136 } 137 138 async_answer_0(rid, rc); 139 } 119 140 120 141 /** Receive a call setting pathname of the program to execute. … … 125 146 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request) 126 147 { 127 ipc_callid_t callid; 128 size_t len; 129 char *name_buf; 130 131 if (!ipc_data_write_receive(&callid, &len)) { 132 ipc_answer_0(callid, EINVAL); 133 ipc_answer_0(rid, EINVAL); 134 return; 135 } 136 137 name_buf = malloc(len + 1); 138 if (!name_buf) { 139 ipc_answer_0(callid, ENOMEM); 140 ipc_answer_0(rid, ENOMEM); 141 return; 142 } 143 144 ipc_data_write_finalize(callid, name_buf, len); 145 ipc_answer_0(rid, EOK); 146 147 if (pathname != NULL) { 148 free(pathname); 149 pathname = NULL; 150 } 151 152 name_buf[len] = '\0'; 153 pathname = name_buf; 148 char *buf; 149 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 150 151 if (rc == EOK) { 152 if (pathname != NULL) 153 free(pathname); 154 155 pathname = buf; 156 } 157 158 async_answer_0(rid, rc); 154 159 } 155 160 … … 161 166 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request) 162 167 { 163 ipc_callid_t callid; 164 size_t buf_size, arg_size; 165 char *p; 166 int n; 167 168 if (!ipc_data_write_receive(&callid, &buf_size)) { 169 ipc_answer_0(callid, EINVAL); 170 ipc_answer_0(rid, EINVAL); 171 return; 172 } 173 174 if (arg_buf != NULL) { 175 free(arg_buf); 176 arg_buf = NULL; 177 } 178 179 if (argv != NULL) { 180 free(argv); 181 argv = NULL; 182 } 183 184 arg_buf = malloc(buf_size + 1); 185 if (!arg_buf) { 186 ipc_answer_0(callid, ENOMEM); 187 ipc_answer_0(rid, ENOMEM); 188 return; 189 } 190 191 ipc_data_write_finalize(callid, arg_buf, buf_size); 192 193 arg_buf[buf_size] = '\0'; 194 195 /* 196 * Count number of arguments 197 */ 198 p = arg_buf; 199 n = 0; 200 while (p < arg_buf + buf_size) { 201 arg_size = str_size(p); 202 p = p + arg_size + 1; 203 ++n; 204 } 205 206 /* Allocate argv */ 207 argv = malloc((n + 1) * sizeof(char *)); 208 209 if (argv == NULL) { 210 free(arg_buf); 211 ipc_answer_0(rid, ENOMEM); 212 return; 213 } 214 215 /* 216 * Fill argv with argument pointers 217 */ 218 p = arg_buf; 219 n = 0; 220 while (p < arg_buf + buf_size) { 221 argv[n] = p; 222 223 arg_size = str_size(p); 224 p = p + arg_size + 1; 225 ++n; 226 } 227 228 argc = n; 229 argv[n] = NULL; 230 231 ipc_answer_0(rid, EOK); 168 char *buf; 169 size_t buf_size; 170 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size); 171 172 if (rc == EOK) { 173 /* 174 * Count number of arguments 175 */ 176 char *cur = buf; 177 int count = 0; 178 179 while (cur < buf + buf_size) { 180 size_t arg_size = str_size(cur); 181 cur += arg_size + 1; 182 count++; 183 } 184 185 /* 186 * Allocate new argv 187 */ 188 char **_argv = (char **) malloc((count + 1) * sizeof(char *)); 189 if (_argv == NULL) { 190 free(buf); 191 async_answer_0(rid, ENOMEM); 192 return; 193 } 194 195 /* 196 * Fill the new argv with argument pointers 197 */ 198 cur = buf; 199 count = 0; 200 while (cur < buf + buf_size) { 201 _argv[count] = cur; 202 203 size_t arg_size = str_size(cur); 204 cur += arg_size + 1; 205 count++; 206 } 207 _argv[count] = NULL; 208 209 /* 210 * Copy temporary data to global variables 211 */ 212 if (arg_buf != NULL) 213 free(arg_buf); 214 215 if (argv != NULL) 216 free(argv); 217 218 argc = count; 219 arg_buf = buf; 220 argv = _argv; 221 } 222 223 async_answer_0(rid, rc); 232 224 } 233 225 … … 239 231 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 240 232 { 241 ipc_callid_t callid;233 fdi_node_t *buf; 242 234 size_t buf_size; 243 if (!ipc_data_write_receive(&callid, &buf_size)) { 244 ipc_answer_0(callid, EINVAL); 245 ipc_answer_0(rid, EINVAL); 246 return; 247 } 248 249 if ((buf_size % sizeof(fdi_node_t)) != 0) { 250 ipc_answer_0(callid, EINVAL); 251 ipc_answer_0(rid, EINVAL); 252 return; 253 } 254 255 if (fil_buf != NULL) { 256 free(fil_buf); 257 fil_buf = NULL; 258 } 259 260 if (filv != NULL) { 261 free(filv); 262 filv = NULL; 263 } 264 265 fil_buf = malloc(buf_size); 266 if (!fil_buf) { 267 ipc_answer_0(callid, ENOMEM); 268 ipc_answer_0(rid, ENOMEM); 269 return; 270 } 271 272 ipc_data_write_finalize(callid, fil_buf, buf_size); 273 274 int count = buf_size / sizeof(fdi_node_t); 275 276 /* Allocate filvv */ 277 filv = malloc((count + 1) * sizeof(fdi_node_t *)); 278 279 if (filv == NULL) { 280 free(fil_buf); 281 ipc_answer_0(rid, ENOMEM); 282 return; 283 } 284 285 /* 286 * Fill filv with argument pointers 287 */ 288 int i; 289 for (i = 0; i < count; i++) 290 filv[i] = &fil_buf[i]; 291 292 filc = count; 293 filv[count] = NULL; 294 295 ipc_answer_0(rid, EOK); 235 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 236 sizeof(fdi_node_t), &buf_size); 237 238 if (rc == EOK) { 239 int count = buf_size / sizeof(fdi_node_t); 240 241 /* 242 * Allocate new filv 243 */ 244 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *)); 245 if (_filv == NULL) { 246 free(buf); 247 async_answer_0(rid, ENOMEM); 248 return; 249 } 250 251 /* 252 * Fill the new filv with argument pointers 253 */ 254 int i; 255 for (i = 0; i < count; i++) 256 _filv[i] = &buf[i]; 257 258 _filv[count] = NULL; 259 260 /* 261 * Copy temporary data to global variables 262 */ 263 if (fil_buf != NULL) 264 free(fil_buf); 265 266 if (filv != NULL) 267 free(filv); 268 269 filc = count; 270 fil_buf = buf; 271 filv = _filv; 272 } 273 274 async_answer_0(rid, EOK); 296 275 } 297 276 … … 309 288 if (rc != EE_OK) { 310 289 DPRINTF("Failed to load executable '%s'.\n", pathname); 311 ipc_answer_0(rid, EINVAL);290 async_answer_0(rid, EINVAL); 312 291 return 1; 313 292 } 314 293 315 294 elf_create_pcb(&prog_info, &pcb); 295 296 pcb.cwd = cwd; 316 297 317 298 pcb.argc = argc; … … 324 305 /* Statically linked program */ 325 306 is_dyn_linked = false; 326 ipc_answer_0(rid, EOK);307 async_answer_0(rid, EOK); 327 308 return 0; 328 309 } … … 333 314 DPRINTF("Failed to load interpreter '%s.'\n", 334 315 prog_info.interp); 335 ipc_answer_0(rid, EINVAL);316 async_answer_0(rid, EINVAL); 336 317 return 1; 337 318 } 338 319 339 320 printf("Run interpreter.\n"); 340 printf("entry point: 0x%lx\n", interp_info.entry);341 printf("pcb address: 0x%lx\n", &pcb);342 printf("prog dynamic: 0x%lx\n", prog_info.dynamic);321 printf("entry point: 0x%lx\n", (unsigned long) interp_info.entry); 322 printf("pcb address: 0x%lx\n", (unsigned long) &pcb); 323 printf("prog dynamic: 0x%lx\n", (unsigned long) prog_info.dynamic); 343 324 344 325 is_dyn_linked = true; 345 ipc_answer_0(rid, EOK);326 async_answer_0(rid, EOK); 346 327 347 328 return 0; … … 367 348 /* Dynamically linked program */ 368 349 DPRINTF("Run ELF interpreter.\n"); 369 DPRINTF("Entry point: 0x%lx\n", interp_info.entry);370 371 ipc_answer_0(rid, EOK);350 DPRINTF("Entry point: %p\n", interp_info.entry); 351 352 async_answer_0(rid, EOK); 372 353 program_run(interp_info.entry, &pcb); 373 354 } else { 374 355 /* Statically linked program */ 375 ipc_answer_0(rid, EOK);356 async_answer_0(rid, EOK); 376 357 program_run(prog_info.entry, &pcb); 377 358 } … … 393 374 /* Already have a connection? */ 394 375 if (connected) { 395 ipc_answer_0(iid, ELIMIT);376 async_answer_0(iid, ELIMIT); 396 377 return; 397 378 } … … 400 381 401 382 /* Accept the connection */ 402 ipc_answer_0(iid, EOK);383 async_answer_0(iid, EOK); 403 384 404 385 /* Ignore parameters, the connection is already open */ … … 409 390 callid = async_get_call(&call); 410 391 411 switch (IPC_GET_ METHOD(call)) {392 switch (IPC_GET_IMETHOD(call)) { 412 393 case IPC_M_PHONE_HUNGUP: 413 394 exit(0); 414 395 case LOADER_GET_TASKID: 415 396 ldr_get_taskid(callid, &call); 397 continue; 398 case LOADER_SET_CWD: 399 ldr_set_cwd(callid, &call); 416 400 continue; 417 401 case LOADER_SET_PATHNAME: … … 434 418 break; 435 419 } 436 if ((callid & IPC_CALLID_NOTIFICATION) == 0 && 437 IPC_GET_METHOD(call) != IPC_M_PHONE_HUNGUP) { 420 if (IPC_GET_IMETHOD(call) != IPC_M_PHONE_HUNGUP) { 438 421 DPRINTF("Responding EINVAL to method %d.\n", 439 IPC_GET_ METHOD(call));440 ipc_answer_0(callid, EINVAL);422 IPC_GET_IMETHOD(call)); 423 async_answer_0(callid, EINVAL); 441 424 } 442 425 } … … 447 430 int main(int argc, char *argv[]) 448 431 { 449 ipcarg_t phonead; 450 task_id_t id; 451 int rc; 452 453 connected = false; 454 432 /* Set a handler of incomming connections. */ 433 async_set_client_connection(ldr_connection); 434 455 435 /* Introduce this task to the NS (give it our task ID). */ 456 id = task_get_id();457 rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id));436 task_id_t id = task_get_id(); 437 int rc = async_req_2_0(PHONE_NS, NS_ID_INTRO, LOWER32(id), UPPER32(id)); 458 438 if (rc != EOK) 459 439 return -1; 460 461 /* Set a handler of incomming connections. */462 async_set_client_connection(ldr_connection);463 440 464 441 /* Register at naming service. */ 465 if ( ipc_connect_to_me(PHONE_NS, SERVICE_LOAD, 0, 0, &phonead) != 0)442 if (service_register(SERVICE_LOAD) != EOK) 466 443 return -2; 467 444 468 445 async_manager(); 469 446
Note:
See TracChangeset
for help on using the changeset viewer.
