Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 3100 → Rev 3101

/branches/dynload/uspace/app/iloader/interp.s
1,6 → 1,6
#
# Provide a string to be included in a special DT_INTERP header, even though
# this is a statically-linked executable. This will mark te binary as
# this is a statically-linked executable. This will mark the binary as
# the program loader.
#
.section .interp , ""
/branches/dynload/uspace/app/iloader/include/pcb.h
28,7 → 28,10
 
/** @addtogroup fs
* @{
*/
*/
/** @file
* @brief Program Control Block interface.
*/
 
#ifndef ILOADER_PCB_H_
#define ILOADER_PCB_H_
/branches/dynload/uspace/app/iloader/include/elf_load.h
30,6 → 30,7
* @{
*/
/** @file
* @brief ELF loader structures and public functions.
*/
 
#ifndef ELF_LOAD_H_
/branches/dynload/uspace/app/iloader/main.c
32,6 → 32,15
*/
/**
* @file
* @brief Loads and runs programs from VFS.
*
* The program loader is a special init binary. Its image is used
* to create a new task upon a @c task_spawn syscall. The syscall
* returns the id of a phone connected to the newly created task.
*
* The caller uses this phone to send the pathname and various other
* information to the loader. This is normally done by the C library
* and completely hidden from applications.
*/
 
#include <stdio.h>
47,10 → 56,20
#include <elf_load.h>
#include <pcb.h>
 
/**
* Bias used for loading the dynamic linker. This will be soon replaced
* by automatic placement.
*/
#define RTLD_BIAS 0x80000
 
/** Pathname of the file that will be loaded */
static char *pathname = NULL;
 
/** Receive a call setting pathname of the program to execute.
*
* @param rid
* @param request
*/
void iloader_set_pathname(ipc_callid_t rid, ipc_call_t *request)
{
// ipc_callid_t callid;
86,6 → 105,12
pathname = name_buf;
}
 
/** Load and run the previously selected program.
*
* @param rid
* @param request
* @return 0 on success, !0 on error.
*/
int iloader_run(ipc_callid_t rid, ipc_call_t *request)
{
int rc;
132,6 → 157,11
return 0;
}
 
/** Program loader main function.
*
* Receive and carry out commands (of which the last one should be
* to execute the loaded program).
*/
int main(int argc, char *argv[])
{
ipc_callid_t callid;
/branches/dynload/uspace/app/iloader/elf_load.c
34,7 → 34,13
 
/**
* @file
* @brief Kernel ELF loader.
* @brief Userspace ELF loader.
*
* This module allows loading ELF binaries (both executables and
* shared objects) from VFS. The current implementation allocates
* anonymous memory, fills it with segment data and then adjusts
* the memory areas' flags to the final value. In the future,
* the segments will be mapped directly from the file.
*/
 
#include <stdio.h>
63,6 → 69,21
static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
 
/** Load ELF binary from a file.
*
* Load an ELF binary from the specified file. If the file is
* an executable program, it is loaded unbiased. If it is a shared
* object, it is loaded with the bias @a so_bias. Some information
* extracted from the binary is stored in a elf_info_t structure
* pointed to by @a info.
*
* @param file_name Path to the ELF file.
* @param so_bias Bias to use if the file is a shared object.
* @param info Pointer to a structure for storing information
* extracted from the binary.
*
* @return EOK on success or negative error code.
*/
int elf_load_file(char *file_name, size_t so_bias, elf_info_t *info)
{
elf_ld_t elf;
72,7 → 93,7
 
printf("open and read '%s'...\n", file_name);
 
fd = open(file_name, 0);
fd = open(file_name, O_RDONLY);
if (fd < 0) {
printf("failed opening file\n");
return -1;
89,6 → 110,13
return rc;
}
 
/** Run an ELF executable.
*
* Transfers control to the entry point of an ELF executable loaded
* earlier with elf_load_file(). This function does not return.
*
* @param info Info structure filled earlier by elf_load_file()
*/
void elf_run(elf_info_t *info)
{
(*info->entry)();
96,6 → 124,14
/* not reached */
}
 
/** Create the program control block (PCB).
*
* Create and install the program control block, initialising it
* with program information from @a info.
*
* @param info Program info structure
* @return EOK on success or negative error code
*/
int elf_create_pcb(elf_info_t *info)
{
pcb_t *pcb;
116,10 → 152,15
}
 
 
/** ELF loader
/** Load an ELF binary.
*
* @param header Pointer to ELF header in memory
* @return EE_OK on success
* The @a elf structure contains the loader state, including
* an open file, from which the binary will be loaded,
* a pointer to the @c info structure etc.
*
* @param elf Pointer to loader state buffer.
* @param so_bias Bias to use if the file is a shared object.
* @return EE_OK on success or EE_xx error code.
*/
static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
{
243,8 → 284,7
 
/** Process segment header.
*
* @param entry Segment header.
* @param elf ELF header.
* @param entry Segment header.
*
* @return EE_OK on success, error code otherwise.
*/
276,8 → 316,8
 
/** Load segment described by program header entry.
*
* @param elf Loader state.
* @param entry Program header entry describing segment to be loaded.
* @param elf ELF header.
*
* @return EE_OK on success, error code otherwise.
*/
346,6 → 386,9
printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
/* rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
 
/* Long reads are not possible yet. Load segment picewise */
 
unsigned left, now;
uint8_t *dp;
 
354,11 → 397,14
 
while (left > 0) {
now = 16384;
if (now > left) now=left;
if (now > left) now = left;
 
printf("read %d...", now);
rc = read(elf->fd, dp, now);
printf("->%d\n", rc);
 
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
printf("->%d\n", rc);
 
left -= now;
dp += now;
}
375,8 → 421,8
 
/** Process section header.
*
* @param elf Loader state.
* @param entry Segment header.
* @param elf ELF header.
*
* @return EE_OK on success, error code otherwise.
*/
394,6 → 440,7
}
break;
case SHT_DYNAMIC:
/* Record pointer to dynamic section into info structure */
elf->info->dynamic =
(void *)((uint8_t *)entry->sh_addr + elf->bias);
printf("dynamic section found at 0x%x\n",