kernel/elf.c
elf_status elf_load(elf_ctx *ctx) {
  elf_prog_header ph_addr;
  int i, off;
  // traverse the elf program segment headers
  for (i = 0, off = ctx->ehdr.phoff; i < ctx->ehdr.phnum; i++, off += sizeof(ph_addr)) {
    // read segment headers
    if (elf_fpread(ctx, (void *)&ph_addr, sizeof(ph_addr), off) != sizeof(ph_addr)) return EL_EIO;

    if (ph_addr.type != ELF_PROG_LOAD) continue;
    if (ph_addr.memsz < ph_addr.filesz) return EL_ERR;
    if (ph_addr.vaddr + ph_addr.memsz < ph_addr.vaddr) return EL_ERR;

    // allocate memory before loading
    void *dest = elf_alloc_mb(ctx, ph_addr.vaddr, ph_addr.vaddr, ph_addr.memsz);

    // actual loading
    if (elf_fpread(ctx, dest, ph_addr.memsz, ph_addr.off) != ph_addr.memsz)
      return EL_EIO;

    // record the vm region in proc->mapped_info
    int j;
    for( j=0; j<PGSIZE/sizeof(mapped_region); j++ )
      if( (process*)(((elf_info*)(ctx->info))->p)->mapped_info[j].va == 0x0 ) break;

    ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].va = ph_addr.vaddr;
    ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].npages = 1;
    if( ph_addr.flags == (SEGMENT_READABLE|SEGMENT_EXECUTABLE) ){
      ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].seg_type = CODE_SEGMENT;
      sprint( "CODE_SEGMENT added at mapped info offset:%d\n", j );
    }else if ( ph_addr.flags == (SEGMENT_READABLE|SEGMENT_WRITABLE) ){
      ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].seg_type = DATA_SEGMENT;
      sprint( "DATA_SEGMENT added at mapped info offset:%d\n", j );
    }else
      panic( "unknown program segment encountered, segment flag:%d.\n", ph_addr.flags );

    ((process*)(((elf_info*)(ctx->info))->p))->total_mapped_region ++;
  }

  return EL_OK;
}
//
// load the elf segments to memory regions
//
load the elf segments to memory regions
load the elf segments to memory regions
elf_status elf_load(elf_ctx *ctx) {
  elf_prog_header ph_addr;
  int i, off;
  for (i = 0, off = ctx->ehdr.phoff; i < ctx->ehdr.phnum; i++, off += sizeof(ph_addr)) {
    if (elf_fpread(ctx, (void *)&ph_addr, sizeof(ph_addr), off) != sizeof(ph_addr)) return EL_EIO;
    if (ph_addr.type != ELF_PROG_LOAD) continue;
    if (ph_addr.memsz < ph_addr.filesz) return EL_ERR;
    if (ph_addr.vaddr + ph_addr.memsz < ph_addr.vaddr) return EL_ERR;
    void *dest = elf_alloc_mb(ctx, ph_addr.vaddr, ph_addr.vaddr, ph_addr.memsz);
    if (elf_fpread(ctx, dest, ph_addr.memsz, ph_addr.off) != ph_addr.memsz)
      return EL_EIO;
    int j;
    for( j=0; j<PGSIZE/sizeof(mapped_region); j++ )
      if( (process*)(((elf_info*)(ctx->info))->p)->mapped_info[j].va == 0x0 ) break;
    ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].va = ph_addr.vaddr;
    ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].npages = 1;
    if( ph_addr.flags == (SEGMENT_READABLE|SEGMENT_EXECUTABLE) ){
      ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].seg_type = CODE_SEGMENT;
      sprint( "CODE_SEGMENT added at mapped info offset:%d\n", j );
    }else if ( ph_addr.flags == (SEGMENT_READABLE|SEGMENT_WRITABLE) ){
      ((process*)(((elf_info*)(ctx->info))->p))->mapped_info[j].seg_type = DATA_SEGMENT;
      sprint( "DATA_SEGMENT added at mapped info offset:%d\n", j );
    }else
      panic( "unknown program segment encountered, segment flag:%d.\n", ph_addr.flags );
    ((process*)(((elf_info*)(ctx->info))->p))->total_mapped_region ++;
  }
  return EL_OK;
}
elf_status elf_load ( elf_ctx * ctx ) { elf_prog_header ph_addr ; int i , off ; for ( i = 0 , off = ctx -> ehdr . phoff ; i < ctx -> ehdr . phnum ; i ++ , off += sizeof ( ph_addr ) ) { if ( elf_fpread ( ctx , ( void * ) & ph_addr , sizeof ( ph_addr ) , off ) != sizeof ( ph_addr ) ) return EL_EIO ; if ( ph_addr . type != ELF_PROG_LOAD ) continue ; if ( ph_addr . memsz < ph_addr . filesz ) return EL_ERR ; if ( ph_addr . vaddr + ph_addr . memsz < ph_addr . vaddr ) return EL_ERR ; void * dest = elf_alloc_mb ( ctx , ph_addr . vaddr , ph_addr . vaddr , ph_addr . memsz ) ; if ( elf_fpread ( ctx , dest , ph_addr . memsz , ph_addr . off ) != ph_addr . memsz ) return EL_EIO ; int j ; for ( j = 0 ; j < PGSIZE / sizeof ( mapped_region ) ; j ++ ) if ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) -> mapped_info [ j ] . va == 0x0 ) break ; ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) ) -> mapped_info [ j ] . va = ph_addr . vaddr ; ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) ) -> mapped_info [ j ] . npages = 1 ; if ( ph_addr . flags == ( SEGMENT_READABLE | SEGMENT_EXECUTABLE ) ) { ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) ) -> mapped_info [ j ] . seg_type = CODE_SEGMENT ; sprint ( " \n " , j ) ; } else if ( ph_addr . flags == ( SEGMENT_READABLE | SEGMENT_WRITABLE ) ) { ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) ) -> mapped_info [ j ] . seg_type = DATA_SEGMENT ; sprint ( " \n " , j ) ; } else panic ( " \n " , ph_addr . flags ) ; ( ( process * ) ( ( ( elf_info * ) ( ctx -> info ) ) -> p ) ) -> total_mapped_region ++ ; } return EL_OK ; }
load the elf segments to memory regions
load the elf segments to memory regions
// traverse the elf program segment headers // read segment headers // allocate memory before loading // actual loading // record the vm region in proc->mapped_info