Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 2963 → Rev 2964

/branches/dynload/uspace/app/iloader/elf_load.c
61,15 → 61,15
"irrecoverable error"
};
 
static unsigned int elf_load(int fd, elf_header_t *header);
static int segment_header(int fd, elf_header_t *elf);
static int section_header(int fd, elf_header_t *elf);
static int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf);
static unsigned int elf_load(elf_ld_t *elf);
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
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);
 
typedef void (*entry_point_t)(void);
int elf_load_file(char *file_name, elf_info_t *info)
{
elf_ld_t elf;
 
int elf_load_file(char *file_name, elf_header_t *header)
{
int fd;
int rc;
 
81,7 → 81,10
return -1;
}
 
rc = elf_load(fd, header);
elf.fd = fd;
elf.info = info;
 
rc = elf_load(&elf);
printf("elf_load() -> %d\n", rc);
 
close(fd);
89,17 → 92,14
return rc;
}
 
void elf_run(elf_header_t *header)
void elf_run(elf_info_t *info)
{
entry_point_t entry_point;
(*info->entry)();
 
entry_point = (entry_point_t)header->e_entry;
(*entry_point)();
 
/* not reached */
}
 
int elf_create_pcb(elf_header_t *header)
int elf_create_pcb(elf_info_t *info)
{
pcb_t *pcb;
void *a;
112,7 → 112,7
return EE_MEMORY;
}
 
pcb->entry = (entry_point_t)header->e_entry;
pcb->entry = info->entry;
 
return 0;
}
123,16 → 123,20
* @param header Pointer to ELF header in memory
* @return EE_OK on success
*/
static unsigned int elf_load(int fd, elf_header_t *header)
static unsigned int elf_load(elf_ld_t *elf)
{
elf_header_t header_buf;
elf_header_t *header = &header_buf;
int i, rc;
 
rc = read(fd, header, sizeof(elf_header_t));
rc = read(elf->fd, header, sizeof(elf_header_t));
if (rc < 0) {
printf("read error\n");
return EE_INVALID;
}
 
elf->header = header;
 
printf("ELF-load:");
/* Identify ELF */
if (header->e_ident[EI_MAG0] != ELFMAG0 ||
164,18 → 168,27
printf("Object type %d is not supported\n", header->e_type);
return EE_UNSUPPORTED;
}
if (header->e_type == ET_DYN) header->e_entry += RTLD_BIAS;
 
/* The run-time dynamic linker is loaded with a bias */
if (header->e_type == ET_DYN)
elf->bias = RTLD_BIAS;
else
elf->bias = 0;
 
printf("parse segments\n");
 
/* Walk through all segment headers and process them. */
for (i = 0; i < header->e_phnum; i++) {
elf_segment_header_t segment_hdr;
 
/* Seek to start of segment header */
lseek(fd, header->e_phoff + i * sizeof(elf_segment_header_t),
SEEK_SET);
lseek(elf->fd, header->e_phoff
+ i * sizeof(elf_segment_header_t), SEEK_SET);
 
rc = segment_header(fd, header);
rc = read(elf->fd, &segment_hdr, sizeof(elf_segment_header_t));
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
 
rc = segment_header(elf, &segment_hdr);
if (rc != EE_OK)
return rc;
}
184,16 → 197,23
 
/* Inspect all section headers and proccess them. */
for (i = 0; i < header->e_shnum; i++) {
elf_section_header_t section_hdr;
 
/* Seek to start of section header */
lseek(fd, header->e_shoff + i * sizeof(elf_section_header_t),
SEEK_SET);
lseek(elf->fd, header->e_shoff
+ i * sizeof(elf_section_header_t), SEEK_SET);
 
rc = section_header(fd, header);
rc = read(elf->fd, &section_hdr, sizeof(elf_section_header_t));
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
 
rc = section_header(elf, &section_hdr);
if (rc != EE_OK)
return rc;
}
 
elf->info->entry =
(entry_point_t)((uint8_t *)header->e_entry + elf->bias);
 
printf("done\n");
 
return EE_OK;
219,21 → 239,14
*
* @return EE_OK on success, error code otherwise.
*/
static int segment_header(int fd, elf_header_t *elf)
static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
{
static elf_segment_header_t entry_buf;
elf_segment_header_t *entry = &entry_buf;
int rc;
 
rc = read(fd, entry, sizeof(elf_segment_header_t));
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
 
switch (entry->p_type) {
case PT_NULL:
case PT_PHDR:
break;
case PT_LOAD:
return load_segment(fd, entry, elf);
return load_segment(elf, entry);
break;
case PT_DYNAMIC:
case PT_INTERP:
256,7 → 269,7
*
* @return EE_OK on success, error code otherwise.
*/
int load_segment(int fd, elf_segment_header_t *entry, elf_header_t *elf)
int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
{
void *a;
int flags = 0;
266,7 → 279,7
printf("load segment at addr 0x%x, size 0x%x\n", entry->p_vaddr,
entry->p_memsz);
bias = (elf->e_type == ET_DYN) ? RTLD_BIAS : 0;
bias = elf->bias;
 
if (entry->p_align > 1) {
if ((entry->p_offset % entry->p_align) !=
318,7 → 331,7
* Load segment data
*/
printf("seek to %d\n", entry->p_offset);
rc = lseek(fd, entry->p_offset, SEEK_SET);
rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
if (rc < 0) { printf("seek error\n"); return EE_INVALID; }
 
printf("read 0x%x bytes to address 0x%x\n", entry->p_filesz, entry->p_vaddr+bias);
334,7 → 347,7
now = 4096;
if (now > left) now=left;
printf("read %d...", now);
rc = read(fd, dp, now);
rc = read(elf->fd, dp, now);
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
printf("->%d\n", rc);
left -= now;
351,15 → 364,8
*
* @return EE_OK on success, error code otherwise.
*/
static int section_header(int fd, elf_header_t *elf)
static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
{
static elf_section_header_t entry_buf;
elf_section_header_t *entry = &entry_buf;
int rc;
 
rc = read(fd, entry, sizeof(elf_section_header_t));
if (rc < 0) { printf("read error\n"); return EE_INVALID; }
 
switch (entry->sh_type) {
case SHT_PROGBITS:
if (entry->sh_flags & SHF_TLS) {
372,7 → 378,10
}
break;
case SHT_DYNAMIC:
printf("dynamic section found\n");
elf->info->dynamic =
(void *)((uint8_t *)entry->sh_addr + elf->bias);
printf("dynamic section found at 0x%x\n",
(uintptr_t)elf->info->dynamic);
break;
default:
break;