add el (tentative)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@154 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
shirait 2007-07-02 08:08:08 +00:00
parent 08109c64b6
commit 9dd92e3eee
25 changed files with 4410 additions and 1 deletions

View File

@ -539,7 +539,7 @@ static BOOL sdi_get_nom( u32 MIN_NOM)
u32 SS = 512; //セクタサイズ(FIX)
u32 SC, n, MAX, SFdash;
u16 i;
RSC[0] = 1; //FAT12,16では1
RSC[1] = 1;
RSC[2] = 1;

View File

@ -0,0 +1,66 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - libraries - el/ARM7
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
TWL_CODEGEN_ALL ?= True
# Codegen for sub processer
TWL_PROC = ARM7
SRCDIR = ../common .
SRCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/el/common/src \
$(TWL_NITROSDK_ROOT)/build/libraries/el/ARM7/src \
INCDIR = ../common
INCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/el/common/include \
SRCS = arch.c \
elf.c \
elf_loader.c \
loader_subset.c \
TARGET_LIB = libel_sp$(TWL_LIBSUFFIX).a
#----------------------------------------------------------------------------
# DEBUG版ビルドの場合、RELEASE版でビルドして
# DEBUG版のライブラリを装います。
ifdef NITRO_DEBUG
NITRO_BUILD_TYPE = RELEASE
endif
include $(TWLSDK_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(TWL_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,53 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - libraries - el/ARM9
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
# build ARM & THUMB libraries
TWL_CODEGEN_ALL ?= True
SRCDIR = ../common .
SRCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/el/common/src \
$(TWL_NITROSDK_ROOT)/build/libraries/el/ARM9/src \
INCDIR = ../common
INCDIR += $(TWL_NITROSDK_ROOT)/build/libraries/el/common/include \
SRCS = arch.c \
elf.c \
elf_loader.c \
loader_subset.c \
TARGET_LIB = libel$(TWL_LIBSUFFIX).a
include $(TWLSDK_ROOT)/build/buildtools/commondefs
INSTALL_TARGETS = $(TARGETS)
INSTALL_DIR = $(TWL_INSTALL_LIBDIR)
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,34 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - libraries - el
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = ARM9
#ifdef TWL_WITH_ARM7
SUBDIRS += ARM7
#endif
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,20 @@
#
# Makefile
#
L_MAIN_DIR := ../../..
include $(L_MAIN_DIR)/make/Makefile.defs
L_TARGETS := libel.a
L_SOURCES := elf.c arch.c elf_loader.c loader_subset.c
L_INCLUDES := -I. \
-I$(D_MAIN_DIR)/include/el \
L_LDLIBS :=
L_DEFS :=
L_DEPENDANCIES :=
include $(D_MAIN_DIR)/make/Makefile.rules

View File

@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: arch.c
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#include "el_config.h"
#if (TARGET_OS_NITRO == 1)
#include <twl.h>
#else
#include <ctr.h>
#endif
#include "arch.h"
/*---------------------------------------------------------
--------------------------------------------------------*/
u32 AR_GetEntrySize( ArchHdr* ArHdr)
{
u16 i;
u32 digit = 1;
u32 size = 0;
/*----- 何桁あるか調べる -----*/
for( i=0; i<10; i++) {
if( ArHdr->ar_size[i] == 0x20) {
break;
}else{
digit *= 10;
}
}
digit /= 10;
/*----------------------------*/
/*----- サイズを算出する -----*/
for( i=0; i<10; i++) {
size += (*(((u8*)(ArHdr->ar_size))+i) - 0x30) * digit; //charをu8に変換
if( digit == 1) {
break;
}else{
digit /= 10;
}
}
/*----------------------------*/
return size;
}

View File

@ -0,0 +1,51 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: arch.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef ARCH_H_
#define ARCH_H_
/*---------------------------------------------------------
Archive Header
--------------------------------------------------------*/
#define ARMAG "!<arch>\n" /* magic string */
#define SARMAG 8 /* length of magic string */
#define ARFMAG "\`\n" /* header trailer string */
#define AR_NAME_LEN 16 /* ar_name size, includes `/' */
typedef struct /* archive file member header - printable ascii */
{
char ar_name[16]; /* file member name - `/' terminated */
char ar_date[12]; /* file member date - decimal */
char ar_uid[6]; /* file member user id - decimal */
char ar_gid[6]; /* file member group id - decimal */
char ar_mode[8]; /* file member mode - octal */
char ar_size[10]; /* file member size - decimal */
char ar_fmag[2]; /* ARFMAG - string to end header */
}ArchHdr; /* 計60(0x3C)バイト */
/*---------------------------------------------------------
--------------------------------------------------------*/
u32 AR_GetEntrySize( ArchHdr* ArHdr);
#endif /*ARCH_H_*/

View File

@ -0,0 +1,94 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader Configuration
File: el_config.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef __ELF_LOADER_CONFIG_H__
#define __ELF_LOADER_CONFIG_H__
/***********************************************************************
ON/OFF
***********************************************************************/
#define DEBUG_PRINT_ON (0)
/***********************************************************************
OS指定
***********************************************************************/
#define TARGET_OS_NITRO (1)
#define TARGET_OS_CTR (TARGET_OS_NITRO ^ 1)
/***********************************************************************
ARMアーキテクチャ指定ARM7TDMIはV4にする
***********************************************************************/
#ifdef SDK_ARM7
#define TARGET_ARM_V4 (1)
#else
#define TARGET_ARM_V4 (0)
#endif
#define TARGET_ARM_V5 (TARGET_ARM_V4 ^ 1)
/***********************************************************************
NITRO OSのとき
***********************************************************************/
#if (TARGET_OS_NITRO == 1)
#if( DEBUG_PRINT_ON == 1)
#define PRINTDEBUG OS_TPrintf
#else
#define PRINTDEBUG( ...) ((void)0)
#endif
#define OSAPI_CPUFILL8 MI_CpuFill8
#define OSAPI_CPUCOPY8 MI_CpuCopy8
#define OSAPI_MALLOC OS_Alloc
#define OSAPI_FREE OS_Free
#define OSAPI_STRLEN STD_GetStringLength
#define OSAPI_STRNCMP STD_CompareNString
#define OSAPI_STRCMP STD_CompareString
#define OSAPI_FLUSHCACHEALL DC_FlushAll
#define OSAPI_WAITCACHEBUF DC_WaitWriteBufferEmpty
/***********************************************************************
CTR OSのとき
***********************************************************************/
#else
#if (DEBUG_PRINT_ON == 1)
#if (CTR_DEF_ENVIRONMENT_DSEMU == 1)
#define PRINTDEBUG osTPrintf
#else
#include <ctr/vlink.h>
#define PRINTDEBUG vlink_dos_printf
#endif
#else
#define PRINTDEBUG( ...) ((void)0)
#endif
#define OSAPI_CPUFILL8 miCpuFill8
#define OSAPI_CPUCOPY8 miCpuCopy8
#define OSAPI_MALLOC i_elAlloc
#define OSAPI_FREE i_elFree
#define OSAPI_STRLEN strlen
#define OSAPI_STRNCMP strncmp
#define OSAPI_STRCMP strcmp
#define OSAPI_FLUSHCACHEALL osFlushDCacheAll
#define OSAPI_WAITCACHEBUF osWaitWriteBufferEmpty
#endif
#endif /*__ELF_LOADER_CONFIG_H__*/

View File

@ -0,0 +1,351 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: elf.c
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#include "el_config.h"
#if (TARGET_OS_NITRO == 1)
#include <twl.h>
#else
#include <ctr.h>
#endif
#include "elf.h"
static int endian;
static BOOL load_strndx_done = FALSE;
/*---------------------------------------------------------
--------------------------------------------------------*/
static u8 *load_elf32_byte(u8 *dest, u8 *org, int lsb)
{
u8 *temp_ptr;
temp_ptr = (u8 *)org;
*dest = *temp_ptr;
temp_ptr++;
return temp_ptr;
}
/*---------------------------------------------------------
--------------------------------------------------------*/
static u8 *load_elf32_half(Elf32_Half *dest, u8 *org, int lsb)
{
u8 *temp_ptr;
temp_ptr = (u8 *)org;
if( lsb == ELFDATA2LSB ) {
*dest = (u16)((u16)(*temp_ptr) & 0x00ff);
temp_ptr++;
*dest |= ((u16)(*temp_ptr) << 8 ) & 0xff00;
temp_ptr++;
}
else /* ELFDATA2MSB */ {
*dest = (u16)(((u16)(*temp_ptr) << 8 ) & 0xff00);
temp_ptr++;
*dest |= ((u16)(*temp_ptr) & 0x00ff);
temp_ptr++;
}
return (void *)temp_ptr;
}
/*---------------------------------------------------------
--------------------------------------------------------*/
static u8 *load_elf32_sword(Elf32_Sword *dest, u8 *org, int lsb)
{
u8 *temp_ptr;
u32 temp;
temp_ptr = (u8 *)org;
if( lsb == ELFDATA2LSB ) {
temp = ((u32)(*temp_ptr) & 0x000000ff);
temp_ptr++;
temp |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
temp_ptr++;
temp |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
temp_ptr++;
temp |= (((u32)(*temp_ptr) << 24 ) & 0xff000000);
temp_ptr++;
}
else /* ELFDATA2MSB */ {
temp = (((u32)(*temp_ptr) << 24 ) & 0xff000000);
temp_ptr++;
temp |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
temp_ptr++;
temp |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
temp_ptr++;
temp |= ((u32)(*temp_ptr) & 0x000000ff);
temp_ptr++;
}
*dest = *( (Elf32_Sword *)&temp );
return (void *)temp_ptr;
}
static u8 *load_elf32_word(Elf32_Word *dest, u8 *org, int lsb)
{
u8 *temp_ptr;
temp_ptr = (u8 *)org;
if( lsb == ELFDATA2LSB ) {
*dest = ((u32)(*temp_ptr) & 0x000000ff);
temp_ptr++;
*dest |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
temp_ptr++;
*dest |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
temp_ptr++;
*dest |= (((u32)(*temp_ptr) << 24 ) & 0xff000000);
temp_ptr++;
}
else /* ELFDATA2MSB */ {
*dest = (((u32)(*temp_ptr) << 24 ) & 0xff000000);
temp_ptr++;
*dest |= (((u32)(*temp_ptr) << 16 ) & 0x00ff0000);
temp_ptr++;
*dest |= (((u32)(*temp_ptr) << 8 ) & 0x0000ff00);
temp_ptr++;
*dest |= ((u32)(*temp_ptr) & 0x000000ff);
temp_ptr++;
}
return (void *)temp_ptr;
}
/*---------------------------------------------------------
ELFヘッダを読み出す
buf : ELFヘッダのアドレス
ehdr :
--------------------------------------------------------*/
void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr)
{
u8 *file_ptr;
if( !buf ) {
return NULL;
}
file_ptr = (u8 *)buf;
/* バッファにコピー */
OSAPI_CPUCOPY8( (void*)file_ptr, ehdr->e_ident, EI_NIDENT);
file_ptr += EI_NIDENT;
/* Magic number */
if( ehdr->e_ident[EI_MAG0] != ELFMAG0 ) {
return NULL;
}
if( ehdr->e_ident[EI_MAG1] != ELFMAG1 ) {
return NULL;
}
if( ehdr->e_ident[EI_MAG2] != ELFMAG2 ) {
return NULL;
}
if( ehdr->e_ident[EI_MAG3] != ELFMAG3 ) {
return NULL;
}
/* CLASS */
switch( ehdr->e_ident[EI_CLASS] ) {
case ELFCLASSNONE:
break;
case ELFCLASS32:
break;
case ELFCLASS64:
break;
default:
break;
}
/* DATA */
switch( ehdr->e_ident[EI_DATA] ) {
case ELFDATANONE:
break;
case ELFDATA2LSB:
endian = ELFDATA2LSB;
break;
case ELFDATA2MSB:
endian = ELFDATA2MSB;
break;
default:
break;
}
/* TYPE */
file_ptr = load_elf32_half(&(ehdr->e_type), file_ptr, endian);
switch( ehdr->e_type ) {
case ET_NONE:
break;
case ET_REL:
break;
case ET_EXEC:
break;
case ET_DYN:
break;
case ET_CORE:
break;
case ET_LOPROC:
break;
case ET_HIPROC:
break;
default:
break;
}
/*---------- ELFヘッダ表示 ----------*/
PRINTDEBUG( "\nELF Header:\n");
file_ptr = load_elf32_half(&(ehdr->e_machine), file_ptr, endian);
PRINTDEBUG("e_machine = %d\n",ehdr->e_machine);
file_ptr = load_elf32_word(&(ehdr->e_version), file_ptr, endian);
PRINTDEBUG("e_version = %d\n",ehdr->e_version);
file_ptr = load_elf32_word(&(ehdr->e_entry), file_ptr, endian);
PRINTDEBUG("e_entry(entry point) = 0x%08x\n",ehdr->e_entry);
file_ptr = load_elf32_word(&(ehdr->e_phoff), file_ptr, endian);
PRINTDEBUG("e_phoff(program header offset) = 0x%08x\n",ehdr->e_phoff);
file_ptr = load_elf32_word(&(ehdr->e_shoff), file_ptr, endian);
PRINTDEBUG("e_shoff(section header offset) = 0x%08x\n",ehdr->e_shoff);
file_ptr = load_elf32_word(&(ehdr->e_flags), file_ptr, endian);
PRINTDEBUG("e_flags = 0x%08x\n",ehdr->e_flags);
if( ehdr->e_flags & EF_ARM_HASENTRY ) {
PRINTDEBUG("has entry\n");
}
if( ehdr->e_flags & EF_ARM_SYMSARESORTED ) {
PRINTDEBUG("symbols are sorted\n");
}
if( ehdr->e_flags & EF_ARM_DYNSYMSUSESEGIDX ) {
PRINTDEBUG("dynamic symbols use segmnet index\n");
}
if( ehdr->e_flags & EF_ARM_MAPSYMSFIRST ) {
PRINTDEBUG("map symbols first\n");
}
PRINTDEBUG("EABI version %x \n", (ehdr->e_flags & EF_ARM_EABIMASK) >> 24 );
file_ptr = load_elf32_half(&(ehdr->e_ehsize), file_ptr, endian);
PRINTDEBUG("e_ehsize = %d\n",ehdr->e_ehsize);
file_ptr = load_elf32_half(&(ehdr->e_phentsize), file_ptr, endian);
PRINTDEBUG("e_phentsize = %d\n",ehdr->e_phentsize);
file_ptr = load_elf32_half(&(ehdr->e_phnum), file_ptr, endian);
PRINTDEBUG("e_phnum = %d\n",ehdr->e_phnum);
file_ptr = load_elf32_half(&(ehdr->e_shentsize), file_ptr, endian);
PRINTDEBUG("e_shentsize = %d\n",ehdr->e_shentsize);
file_ptr = load_elf32_half(&(ehdr->e_shnum), file_ptr, endian);
PRINTDEBUG("e_shnum = %d\n",ehdr->e_shnum);
file_ptr = load_elf32_half(&(ehdr->e_shstrndx), file_ptr, endian);
PRINTDEBUG("e_shstrndx(section index no. of the section header string table section = %d\n",ehdr->e_shstrndx);
PRINTDEBUG( "\n");
/*-----------------------------------*/
return file_ptr;
}
/*---------------------------------------------------------
Relocation Entry Load
--------------------------------------------------------*/
static void *ELF_LoadRel(const void *buf, Elf32_Rel *rel)
{
u8 *file_ptr;
if( !buf ) {
return NULL;
}
file_ptr = (u8 *)buf;
file_ptr = load_elf32_word(&(rel->r_offset), file_ptr, endian);
file_ptr = load_elf32_word(&(rel->r_info), file_ptr, endian);
return file_ptr;
}
static void *ELF_LoadRela(const void *buf, Elf32_Rela *rela)
{
u8 *file_ptr;
if( !buf ) {
return NULL;
}
file_ptr = (u8 *)buf;
file_ptr = load_elf32_word(&(rela->r_offset), file_ptr, endian);
file_ptr = load_elf32_word(&(rela->r_info), file_ptr, endian);
file_ptr = load_elf32_sword(&(rela->r_addend), file_ptr, endian);
return file_ptr;
}
/*---------------------------------------------------------
Symbol Table Entry Load
buf :
sym :
--------------------------------------------------------*/
static void *ELF_LoadSymbol(const void *buf, Elf32_Sym *sym)
{
u8 *file_ptr;
if( !buf ) {
return NULL;
}
file_ptr = (u8 *)buf;
file_ptr = load_elf32_word(&(sym->st_name), file_ptr, endian);
file_ptr = load_elf32_word(&(sym->st_value), file_ptr, endian);
file_ptr = load_elf32_word(&(sym->st_size), file_ptr, endian);
file_ptr = load_elf32_byte(&(sym->st_info), file_ptr, endian);
file_ptr = load_elf32_byte(&(sym->st_other), file_ptr, endian);
file_ptr = load_elf32_half(&(sym->st_shndx), file_ptr, endian);
return file_ptr;
}
/*---------------------------------------------------------
Section Header Load
buf :
shdr :
--------------------------------------------------------*/
static void *ELF_LoadSectionHeader(const void *buf,Elf32_Shdr *shdr)
{
u8 *file_ptr;
if( !buf ) {
return NULL;
}
file_ptr = (u8 *)buf;
file_ptr = load_elf32_word(&(shdr->sh_name), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_type), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_flags), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_addr), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_offset), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_size), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_link), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_info), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_addralign), file_ptr, endian);
file_ptr = load_elf32_word(&(shdr->sh_entsize ), file_ptr, endian);
return file_ptr;
}

View File

@ -0,0 +1,435 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: elf.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef ELF_H_
#define ELF_H_
#include "el_config.h"
#if (TARGET_OS_NITRO == 1)
#else
#include <ctr.h>
#endif
/*---------------------------------------------------------
--------------------------------------------------------*/
typedef u32 Elf32_Addr; /* size:4, align:4 Unsigned program address */
typedef u16 Elf32_Half; /* size:2, align:2 Unsigned medium int */
typedef u32 Elf32_Off; /* size:4, align:4 Unsigned file offset */
typedef s32 Elf32_Sword; /* size:4, align:4 Signed large int */
typedef u32 Elf32_Word; /* size:4, align:4 Unsigned large int */
/*---------------------------------------------------------
ELF Header
--------------------------------------------------------*/
/* e_identのインデックス */
#define EI_MAG0 0 /* File identification */
#define EI_MAG1 1 /* File identification */
#define EI_MAG2 2 /* File identification */
#define EI_MAG3 3 /* File identification */
#define EI_CLASS 4 /* File class 0=invalid, 1=32bit, 2=64bit */
#define EI_DATA 5 /* Data encoding 0=invalid, 1=LSB, 2=MSB */
#define EI_VERSION 6 /* File version 現在は1 */
#define EI_PAD 7 /* Start of padding bytes */
#define EI_NIDENT 16 /* Size of e_ident[] */
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf32_Half e_type; /* ELFの形式(再配置可能, 実行可能など) */
Elf32_Half e_machine; /* ファイルで要求されるアーキテクチャ */
Elf32_Word e_version; /* ELFフォーマットのバージョン現在は1 */
Elf32_Addr e_entry; /* プログラムのエントリポイント。指定無しなら0。 */
Elf32_Off e_phoff; /* プログラムヘッダテーブルのファイル先頭からのオフセット */
Elf32_Off e_shoff; /* セクションヘッダテーブルのファイル先頭からのオフセット */
Elf32_Word e_flags; /* プロセッサ固有のフラグ */
Elf32_Half e_ehsize; /* ELFヘッダのサイズ */
Elf32_Half e_phentsize; /* 1プログラムヘッダのサイズ */
Elf32_Half e_phnum; /* プログラムヘッダの数 */
Elf32_Half e_shentsize; /* 1セクションヘッダのサイズ */
Elf32_Half e_shnum; /* セクションヘッダの数 */
Elf32_Half e_shstrndx; /* セクション名文字列テーブルセクションへのインデックス */
} Elf32_Ehdr;
/* e_ident[EI_*]の中身定義 */
#define ELFMAG0 0x7f
#define ELFMAG1 'E'
#define ELFMAG2 'L'
#define ELFMAG3 'F'
#define ELFCLASSNONE 0 /* invalid */
#define ELFCLASS32 1 /* ARM and Thumb processors use 32-bit ELF. */
#define ELFCLASS64 2
#define ELFDATANONE 0 /* invalid */
#define ELFDATA2LSB 1 /* little-endian */
#define ELFDATA2MSB 2 /* big-endian */
/* [e_type] */
#define ET_NONE 0 /* No file type */
#define ET_REL 1 /* Re-locatable file */
#define ET_EXEC 2 /* Executable file */
#define ET_DYN 3 /* Shared object file */
#define ET_CORE 4 /* Core file */
#define ET_LOPROC 0xff00 /* Processor-specific */
#define ET_HIPROC 0xffff /* Processor-specific */
/* [e_machine] */
#define EM_NONE 0 /* No machine */
#define EM_M32 1
#define EM_SPARC 2
#define EM_386 3
#define EM_68K 4
#define EM_88K 5
#define EM_860 7
#define EM_MIPS 8
#define EM_MIPS_RS4_BE 10
#define EM_ARM 40 /* ARM/Thumb Architecture */
/* [e_version] This member identifies the object file version.*/
#define EV_NONE 0 /* Invalid version */
#define EV_CURRENT 1 /* Current version */
/*
ARM-specific e_flags
e_flags Field Value Meaning
EF_ARM_HASENTRY (0x02) e_entry contains a program-loader entry point
(see section 4.1.1, Entry points, below).
EF_ARM_SYMSARESORTED (0x04) Each subsection of the symbol table is sorted by symbol value
(see section 4.4.8, Symbol table order, below)
EF_ARM_DYNSYMSUSESEGIDX (0x8) Symbols in dynamic symbol tables that are defined in sections
included in program segment n have st_shndx = n + 1.
(see section 4.4.9, Dynamic symbol table entries, below).
EF_ARM_MAPSYMSFIRST (0x10) Mapping symbols precede other local symbols in the symbol table
(see section 4.4.8, Symbol table order, below).
EF_ARM_EABIMASK (0xFF000000)(current version is 0x02000000)
This masks an 8-bit version number, the version of the ARM
EABI to which this ELF file conforms. This EABI is version 2. A
value of 0 denotes unknown conformance.
*/
#define EF_ARM_HASENTRY 0x02
#define EF_ARM_SYMSARESORTED 0x04
#define EF_ARM_DYNSYMSUSESEGIDX 0x8
#define EF_ARM_MAPSYMSFIRST 0x10
#define EF_ARM_EABIMASK 0xFF000000
/*---------------------------------------------------------
Program headers
--------------------------------------------------------*/
typedef struct {
Elf32_Word p_type;
Elf32_Off p_offset;
Elf32_Addr p_vaddr;
Elf32_Addr p_paddr;
Elf32_Word p_filesz;
Elf32_Word p_memsz;
Elf32_Word p_flags;
Elf32_Word p_align;
} Elf32_Phdr;
/* [p_type] */
#define PT_NULL 0 /* 使われないエントリで、他のメンバの値の意味は未定義 */
#define PT_LOAD 1 /* 実行時にロードされるセグメント */
#define PT_DYNAMIC 2 /* 動的構造体配列を保持するセグメント */
#define PT_INTERP 3 /* ファイルの解釈に使われるインタプリタのパスを保持するセグメント */
#define PT_NOTE 4 /* ファイルの解釈には使われない情報を保持するセグメント */
#define PT_SHLIB 5 /* 予約 */
#define PT_PHDR 6 /* プログラムヘッダテーブル(プログラムのメモリイメージの一部である場合のみ存在) */
//#define PT_TLS ? /* スレッド局所記憶領域のテンプレート */
#define PT_LOOS 0x60000000 /* OS固有に予約された領域 */
#define PT_HIOS 0x6fffffff
#define PT_LOPROC 0x70000000 /* プロセッサ固有に予約された領域 */
#define PT_HIPROC 0x7fffffff
/* [p_flags]*/
#define PF_X 1 /*実行可能*/
#define PF_W 2 /*書き込み可能*/
#define PF_R 4 /*読み出し可能*/
#define PF_ARM_SB 0x10000000 /*The segment contains the location addressed by the static base*/
#define PF_ARM_PI 0x20000000 /*The segment is position-independent*/
#define PF_ARM_ENTRY 0x80000000 /*The segment contains the entry point*/
#define PF_MASKPROC 0xf0000000
/*---------------------------------------------------------
Section headers
--------------------------------------------------------*/
typedef struct {
Elf32_Word sh_name; /*セクションヘッダ文字列テーブルセクションのインデックス*/
Elf32_Word sh_type; /* タイプ(下記定義参照) */
Elf32_Word sh_flags;
Elf32_Addr sh_addr; /* */
Elf32_Off sh_offset; /* ファイルの先頭からのオフセット */
Elf32_Word sh_size; /* バイト単位のサイズ */
Elf32_Word sh_link; /* sh_typeによって値の意味が変わる */
Elf32_Word sh_info; /* sh_typeによって値の意味が変わる */
Elf32_Word sh_addralign; /* アラインメント制限(0or1で制限なし,4で4ByteAlign) */
Elf32_Word sh_entsize; /* 固定サイズのエントリテーブルがある場合、1要素のサイズ */
} Elf32_Shdr;
/* sh_addr mod sh_addralign = 0 でなければならない */
/* Section Types, [sh_type] */
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
#define SHT_STRTAB 3
#define SHT_RELA 4
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
#define SHT_NOBITS 8
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
#define SHT_HIUSER 0xffffffff
/* [sh_flags] */
#define SHF_WRITE 0x1
#define SHF_ALLOC 0x2
#define SHF_EXECINSTR 0x4
#define SHF_MASKPROC 0xf0000000
/* ARM-EABI-specific */
#define SHF_ENTRYSECT 0x10000000 /* The section contains an entry point. */
#define SHF_COMDEF 0x80000000 /* The section may be multiply defined in the input to a link step. */
/* others */
#define SHF_LINK_ORDER 0x80
/*セクションインデックス*/
//Sym->st_shndxなど
#define SHN_UNDEF 0
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_HIRESERVE 0xffff
//ここからはヘッダでなく実体データ構造
/*---------------------------------------------------------
Symbol Table Entry
--------------------------------------------------------*/
typedef struct {
Elf32_Word st_name; /* シンボル文字列テーブルのインデックス */
Elf32_Addr st_value; /* おそらく関連するセクション内でのオフセット値 */
Elf32_Word st_size; /* サイズがないか、不明な場合は 0 */
unsigned char st_info; /* バインド と タイプ */
unsigned char st_other; /* 現在は 0 が入る */
Elf32_Half st_shndx; /* 関連するセクションヘッダテーブルのインデックス */
} Elf32_Sym;
/* st_info */
#define ELF32_ST_BIND(i) ((i)>>4)
#define ELF32_ST_TYPE(i) ((i)&0xf)
#define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
/* st_info の BIND */
#define STB_LOCAL 0
#define STB_GLOBAL 1
#define STB_WEAK 2
#define STB_LOPROC 13
#define STB_HIPROC 15
/* st_info の TYPE */
#define STT_NOTYPE 0 /*未定義*/
#define STT_OBJECT 1 /*データオブジェクト*/
#define STT_FUNC 2
#define STT_SECTION 3
#define STT_FILE 4
#define STT_LOPROC 13
#define STT_HIPROC 15
/*---------------------------------------------------------
Relocation Entry
--------------------------------------------------------*/
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
} Elf32_Rel;
typedef struct {
Elf32_Addr r_offset;
Elf32_Word r_info;
Elf32_Sword r_addend;
} Elf32_Rela;
#define ELF32_R_SYM(i) ((i)>>8)
#define ELF32_R_TYPE(i) ((unsigned char)(i))
#define ELF32_R_INFO(s,t) (((s)<<8)+(unsigned char)(t))
/* r_info の TYPE */
#define R_ARM_NONE 0 /* Any No relocation. Encodes dependencies between sections. */
#define R_ARM_PC24 1 /* ARM B/BL S . P + A */
#define R_ARM_ABS32 2 /* 32-bit word S + A */
#define R_ARM_REL32 3 /* 32-bit word S . P + A */
#define R_ARM_PC13 4 /* ARM LDR r, [pc,…] S . P + A */
#define R_ARM_ABS16 5 /* 16-bit half-word S + A */
#define R_ARM_ABS12 6 /* ARM LDR/STR S + A */
#define R_ARM_THM_ABS5 7 /* Thumb LDR/STR S + A */
#define R_ARM_ABS8 8 /* 8-bit byte S + A */
#define R_ARM_SBREL32 9 /* 32-bit word S . B + A */
#define R_ARM_THM_PC22 10 /* Thumb BL pair S . P+ A */
#define R_ARM_THM_PC8 11 /* Thumb LDR r, [pc,…] S . P + A */
#define R_ARM_AMP_VCALL9 12 /* AMP VCALL Obsolete.SA-1500 only. */
#define R_ARM_SWI24 13 /* ARM SWI S + A */
#define R_ARM_THM_SWI8 14 /* Thumb SWI S + A */
#define R_ARM_XPC25 15 /* ARM BLX S . P+ A */
#define R_ARM_THM_XPC22 16 /* Thumb BLX pair S . P+ A */
/* 17-31, reserved to ARM Linux */
//17-19 Reserved to ARM LINUX
#define R_ARM_COPY 20 /* 32 bit word Copy symbol at dynamic link time. */
#define R_ARM_GLOB_DAT 21 /* 32 bit word Create GOT entry. */
#define R_ARM_JUMP_SLOT 22 /* 32 bit word Create PLT entry. */
#define R_ARM_RELATIVE 23 /* 32 bit word Adjust by program base. */
#define R_ARM_GOTOFF 24 /* 32 bit word Offset relative to start of GOT. */
#define R_ARM_GOTPC 25 /* 32 bit word Insert address of GOT. */
#define R_ARM_GOT32 26 /* 32 bit word Entry in GOT. */
#define R_ARM_PLT32 27 /* ARM BL Entry in PLT. */
/* 28-31 Reserved to ARM LINUX */
#define R_ARM_ALU_PCREL_7_0 32 /* ARM ADD/SUB (S . P + A) & 0x000000FF */
#define R_ARM_ALU_PCREL_15_8 33 /* ARM ADD/SUB (S . P + A) & 0x0000FF00 */
#define R_ARM_ALU_PCREL_23_15 34 /* ARM ADD/SUB (S . P + A) & 0x00FF0000 */
#define R_ARM_LDR_SBREL_11_0 35 /* ARM LDR/STR (S . B + A) & 0x00000FFF */
#define R_ARM_ALU_SBREL_19_12 36 /* ARM ADD/SUB (S . B + A) & 0x000FF000 */
#define R_ARM_ALU_SBREL_27_20 37 /* ARM ADD/SUB (S . B + A) & 0x0FF00000 */
#define R_ARM_TARGET1 38
#define R_ARM_ROSEGREL32 39
#define R_ARM_V4BX 40
#define R_ARM_TARGET2 41
#define R_ARM_PREL31 42
/* 96-111, reserved to ARM g++ */
#define R_ARM_GNU_VTENTRY 100 /* 32 bit word Record C++ vtable entry. */
#define R_ARM_GNU_VTINHERIT 101 /* 32 bit word Record C++ member usage. */
#define R_ARM_THM_PC11 102 /* Thumb B S . P + A */
#define R_ARM_THM_PC9 103 /* Thumb B<cond> S . P + A */
/* 112-127, reserved for private experiments */
/* 128-248, reserved to ARM */
#define R_ARM_RXPC25 249 /* ARM BLX (ΔS . ΔP) + A #define For calls between program segments. */
#define R_ARM_RSBREL32 250 /* Word (ΔS . ΔSB) + A For an offset from SB, the static base. */
#define R_ARM_THM_RPC22 251 /* Thumb BL/BLX pair (ΔS . ΔP) + A For calls between program segments. */
#define R_ARM_RREL32 252 /* Word (ΔS . ΔP) + A For on offset between two segments. */
#define R_ARM_RABS32 253 /* Word ΔS + A For the address of a location in the target segment. */
#define R_ARM_RPC24 254 /* ARM B/BL (ΔS . ΔP) + A For calls between program segments. */
#define R_ARM_RBASE 255 /* None None.Identifies the segment being relocated by the following
relocation directives. The ARM EABI poses two problems for relocating
executables and shared objects encoded in */
// shirait
#define R_ARM_LDR_PC_G0 4 //LDR
#define R_ARM_ABS12 6 //LDR, STR
#define R_ARM_THM_CALL 10 //R_ARM_THM_PC22と同じ
#define R_ARM_CALL 28 //BL/BLX
#define R_ARM_JUMP24 29 //B/BL<cond>
#define R_ARM_THM_JUMP24 30
#define R_ARM_MOVW_ABS_NC 43 //MOVW
#define R_ARM_MOVT_ABS 44 //MOVT
#define R_ARM_MOVW_PREL_NC 45 //MOVW
#define R_ARM_MOVT_PREL 46 //MOVT
#define R_ARM_ALU_PC_G0_NC 57 //ADD, SUB
#define R_ARM_ALU_PC_G0 58 //ADD, SUB
#define R_ARM_ALU_PC_G1_NC 59 //ADD, SUB
#define R_ARM_ALU_PC_G1 60 //ADD, SUB
#define R_ARM_ALU_PC_G2 61 //ADD, SUB
#define R_ARM_LDR_PC_G1 62 //LDR, STR, LDRB, STRB
#define R_ARM_LDR_PC_G2 63 //LDR, STR, LDRB, STRB
#define R_ARM_LDRS_PC_G0 64 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDRS_PC_G1 65 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDRS_PC_G2 66 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDC_PC_G0 67 //LDC, STC
#define R_ARM_LDC_PC_G1 68 //LDC, STC
#define R_ARM_LDC_PC_G2 69 //LDC, STC
#define R_ARM_ALU_SB_G0_NC 70 //ADD, SUB
#define R_ARM_ALU_SB_G0 71 //ADD, SUB
#define R_ARM_ALU_SB_G1_NC 72 //ADD, SUB
#define R_ARM_ALU_SB_G1 73 //ADD, SUB
#define R_ARM_ALU_SB_G2 74 //ADD, SUB
#define R_ARM_LDR_SB_G0 75 //LDR, STR, LDRB, STRB
#define R_ARM_LDR_SB_G1 76 //LDR, STR, LDRB, STRB
#define R_ARM_LDR_SB_G2 77 //LDR, STR, LDRB, STRB
#define R_ARM_LDRS_SB_G0 78 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDRS_SB_G1 79 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDRS_SB_G2 80 //LDRD, STRD, LDRH, STRH, LDRSH, LDRSB
#define R_ARM_LDC_SB_G0 81 //LDC, STC
#define R_ARM_LDC_SB_G1 82 //LDC, STC
#define R_ARM_LDC_SB_G2 83 //LDC, STC
#define R_ARM_MOVW_BREL_NC 84 //MOVW
#define R_ARM_MOVT_BREL 85 //MOVT
#define R_ARM_MOVW_BREL 86 //MOVW
#define R_ARM_GOT_BREL12 97 //LDR
#define R_ARM_GOTOFF12 98 //LDR, STR
#define R_ARM_TLS_LDO12 109 //LDR, STR
#define R_ARM_TLS_LE12 110 //LDR, STR
#define R_ARM_TLS_TE12GP 111 //LDR
/*---------------------------------------------------------
Dynamic Section elf_v1.2
--------------------------------------------------------*/
typedef struct {
Elf32_Sword d_tag;
union {
Elf32_Word d_val;
Elf32_Addr d_ptr;
} d_un;
} Elf32_Dyn;
/* Additional symbol types for Thumb. */
#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
/*---------------------------------------------------------
ELFヘッダを読み出す
--------------------------------------------------------*/
void *ELF_LoadELFHeader(const void *buf, Elf32_Ehdr *ehdr);
#endif /* ELF_H_ */

View File

@ -0,0 +1,776 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: elf_loader.c
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#include "el_config.h"
#if (TARGET_OS_NITRO == 1)
#include <twl.h>
#else
#include <ctr.h>
#include <ctr/fs.h>
#include <stdio.h>
#include <string.h>
#endif
#include "elf.h"
#include "elf_loader.h"
#include "arch.h"
#include "loader_subset.h"
//#if (CTR_DEF_ENVIRONMENT_DSEMU == 1)
#if (TARGET_OS_NITRO == 1)
OSHeapHandle EL_Heap;
#endif
ElAdrEntry* ELAdrEntStart = NULL;
ElUnresolvedEntry* ELUnrEntStart = NULL;
/*------------------------------------------------------
-----------------------------------------------------*/
//#if (TARGET_OS_NITRO == 1)
//#else
ElReadImage i_elReadImage;
ElAlloc i_elAlloc;
ElFree i_elFree;
//#endif
/*------------------------------------------------------
-----------------------------------------------------*/
static u16 elLoadSegments( ElDesc* elElfDesc);
static u16 elLoadSections( ElDesc* elElfDesc);
// ELFオブジェクトまたはそのアーカイブをバッファに再配置する
static u16 i_elLoadLibrary( ElDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf);
// ELFオブジェクトをバッファに再配置するコア関数
static u16 i_elLoadObject( ElDesc* elElfDesc, void* obj_offset, void* buf);
// ELFオブジェクトからデータを読み出すスタブ関数
static void i_elReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
static void i_elReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
static void i_elReadUsr( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
/*---------------------------------------------------------
ELFオブジェクトのサイズを求める
buf : ELFイメージのアドレス
--------------------------------------------------------*/
u32 elGetElfSize( const void* buf)
{
Elf32_Ehdr Ehdr;
u32 size;
if( ELF_LoadELFHeader( buf, &Ehdr) == NULL) {
return 0;
}
size = (u32)(Ehdr.e_shoff + (Ehdr.e_shentsize * Ehdr.e_shnum));
return size;
}
/*------------------------------------------------------
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
void elInit( void)
{
void* heap_start;
/*--- メモリアロケーション関係の設定 ---*/
OS_InitArena();
heap_start = OS_InitAlloc( OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1);
OS_SetMainArenaLo( heap_start );
EL_Heap = OS_CreateHeap( OS_ARENA_MAIN, heap_start, (void*)((u32)(OS_GetMainArenaHi())+1));
OS_SetCurrentHeap( OS_ARENA_MAIN, EL_Heap);
/*--------------------------------------*/
}
#else
void elInit( ElAlloc alloc, ElFree free)
{
i_elAlloc = alloc;
i_elFree = free;
}
#endif
/*------------------------------------------------------
ElDesc構造体を初期化する
-----------------------------------------------------*/
BOOL elInitDesc( ElDesc* elElfDesc)
{
if( elElfDesc == NULL) { /*NULLチェック*/
return FALSE;
}
/*初期値の設定*/
elElfDesc->ShdrEx = NULL;
elElfDesc->SymEx = NULL;
elElfDesc->SymExTbl = NULL;
elElfDesc->SymExTarget = 0xFFFFFFFF;
elElfDesc->process = EL_INITIALIZED; /*フラグの設定*/
return TRUE;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
elElfDesc :
ObjFile : OBJファイルまたはアーカイブファイルの構造体
buf :
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
u16 elLoadLibraryfromFile( ElDesc* elElfDesc, FSFile* ObjFile, void* buf)
#else
u16 elLoadLibraryfromFile( ElDesc* elElfDesc, int ObjFile, void* buf)
#endif
{
u16 result;
u32 len;
/*リード関数の設定*/
elElfDesc->i_elReadStub = i_elReadFile;
elElfDesc->FileStruct = (int*)ObjFile;
#if (TARGET_OS_NITRO == 1)
len = FS_GetLength( ObjFile);
#else
len = fsLseek( ObjFile, 0, SEEK_END);
fsLseek( ObjFile, 0, SEEK_SET);
#endif
result = i_elLoadLibrary( elElfDesc, NULL, len, buf);
return result;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
elElfDesc :
readfunc : OBJファイルまたはアーカイブファイルを読み出すユーザ関数
buf :
-----------------------------------------------------*/
//#if (TARGET_OS_NITRO == 1)
//#else
u16 elLoadLibrary( ElDesc* elElfDesc, ElReadImage readfunc, u32 len, void* buf)
{
i_elReadImage = readfunc;
elElfDesc->i_elReadStub = i_elReadUsr;
return( i_elLoadLibrary( elElfDesc, NULL, len, buf));
}
//#endif
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
elElfDesc :
obj_image : OBJファイルまたはアーカイブファイルのRAM上イメージアドレス
buf :
-----------------------------------------------------*/
u16 elLoadLibraryfromMem( ElDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf)
{
u16 result;
/*リード関数の設定*/
elElfDesc->i_elReadStub = i_elReadMem;
elElfDesc->FileStruct = NULL;
result = i_elLoadLibrary( elElfDesc, obj_image, obj_len, buf);
return result;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
elElfDesc :
obj_image : OBJファイルまたはアーカイブファイルのRAM上イメージアドレス
buf :
-----------------------------------------------------*/
static u16 i_elLoadLibrary( ElDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf)
{
u16 result, all_result;
u32 image_pointer;
u32 arch_size;
u32 elf_num = 0; /*ELFオブジェクトの数*/
ArchHdr ArHdr;
char OBJMAG[8];
char ELFMAG[4] = { ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3};
all_result = EL_RELOCATED;
elElfDesc->ar_head = obj_image;
image_pointer = 0;
elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)obj_image, 0, 8); /*OBJの文字列を取得*/
/*--------------- アーカイブファイルの場合 ---------------*/
if( OSAPI_STRNCMP( OBJMAG, ARMAG, 8) == 0) {
arch_size = sizeof( ArchHdr);
image_pointer += 8; /*最初のエントリへ*/
elElfDesc->buf_current = buf;
while( image_pointer < obj_len) {
elElfDesc->i_elReadStub( OBJMAG, elElfDesc->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4); /*OBJの文字列を取得*/
if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
elf_num++;
result = i_elLoadObject( elElfDesc, (void*)(image_pointer+arch_size), elElfDesc->buf_current);
if( result < all_result) { /*悪い結果のときだけall_resultに反映*/
all_result = result;
}
/*初期値の設定*/
elElfDesc->ShdrEx = NULL;
elElfDesc->SymEx = NULL;
elElfDesc->SymExTbl = NULL;
elElfDesc->SymExTarget = 0xFFFFFFFF;
elElfDesc->process = EL_INITIALIZED; /*フラグの設定*/
}else{
}
/*次のエントリへ*/
elElfDesc->i_elReadStub( &ArHdr, elElfDesc->FileStruct, (u32)(obj_image), image_pointer, arch_size);
image_pointer += arch_size + AR_GetEntrySize( &ArHdr);
}
}else{/*--------------- ELFファイルの場合 ---------------*/
if( OSAPI_STRNCMP( OBJMAG, ELFMAG, 4) == 0) {
elf_num++;
all_result = i_elLoadObject( elElfDesc, 0, buf);
}
}
/*-------------------------------------------------------*/
if( elf_num) {
return all_result;
}else{
return EL_FAILED;
}
}
/*------------------------------------------------------
ELFオブジェクトをバッファに再配置する
elElfDesc :
obj_offset : OBJファイルのRAM上イメージアドレスからのオフセット
buf : (TODO:)
-----------------------------------------------------*/
static u16 i_elLoadObject( ElDesc* elElfDesc, void* obj_offset, void* buf)
{
u16 ret_val;
/* ElDescの初期化チェック */
if( elElfDesc->process != EL_INITIALIZED) {
return EL_FAILED;
}
/* ELFヘッダの取得 */
elElfDesc->i_elReadStub( &(elElfDesc->CurrentEhdr), elElfDesc->FileStruct,
(u32)(elElfDesc->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr));
/* ElDesc構造体の構築 */
elElfDesc->elf_offset = obj_offset;
elElfDesc->buf_current = buf;
elElfDesc->shentsize = elElfDesc->CurrentEhdr.e_shentsize;
elElfDesc->entry_adr = elElfDesc->CurrentEhdr.e_entry;
/* ELFファイルタイプ別に処理 */
switch( elElfDesc->CurrentEhdr.e_type) {
case ET_NONE:
PRINTDEBUG( "ERROR : Elf type \"ET_NONE\"\n");
ret_val = EL_FAILED;
break;
case ET_REL: /* 実行×、再配置○ */
PRINTDEBUG( "Elf type \"ET_REL\"\n");
if( buf == NULL) { /* バッファのNULLチェック */
return EL_FAILED;
}
ret_val = elLoadSections( elElfDesc);
break;
case ET_EXEC: /* 実行○、再配置× */
PRINTDEBUG( "Elf type \"ET_EXEC\"\n");
ret_val = elLoadSegments( elElfDesc);
break;
case ET_DYN: /* 実行○、再配置○ (TODO:未テスト)*/
PRINTDEBUG( "Elf type \"ET_DYN\"\n");
if( buf == NULL) { //ロードアドレスが指定されてないときはET_EXEC扱い
ret_val = elLoadSegments( elElfDesc);
}else{ //ロードアドレスが指定されていればET_REL扱い
ret_val = elLoadSections( elElfDesc);
}
break;
case ET_CORE:
PRINTDEBUG( "ERROR : Elf type \"ET_CORE\"\n");
ret_val = EL_FAILED;
break;
default:
PRINTDEBUG( "ERROR : Invalid Elf type 0x%x\n",
elElfDesc->CurrentEhdr.e_type);
ret_val = EL_FAILED;
break;
}
return( ret_val);
}
/*------------------------------------------------------
調
elElfDesc :
-----------------------------------------------------*/
static u16 elLoadSegments( ElDesc* elElfDesc)
{
u16 i;
//u32 load_start;
Elf32_Phdr CurrentPhdr;
for( i=0; i<(elElfDesc->CurrentEhdr.e_phnum); i++) {
/*プログラムヘッダをコピー*/
i_elGetPhdr( elElfDesc, i, &CurrentPhdr);
if( CurrentPhdr.p_type == PT_LOAD) {
/*ロード可能セグメントならメモリにロード*/
i_elCopySegmentToBuffer( elElfDesc, &CurrentPhdr);
}else{
PRINTDEBUG( "WARNING : skip segment (type = 0x%x)\n",
CurrentPhdr.p_type);
}
}
elElfDesc->process = EL_COPIED;
return( elElfDesc->process);
}
/*------------------------------------------------------
調
elElfDesc :
-----------------------------------------------------*/
static u16 elLoadSections( ElDesc* elElfDesc)
{
u16 i;
ElShdrEx* FwdShdrEx;
ElShdrEx* CurrentShdrEx;
ElShdrEx* InfoShdrEx; //例えばCurrentShdrExがrel.textの場合.textをさす
ElShdrEx DmyShdrEx;
#if (DEBUG_PRINT_ON == 1)
u16 j;
u32 num_of_entry;
char sym_str[128]; //デバッグプリント用
u32 offset; //デバッグプリント用
#endif
/*---------- ElShdrExのリストを作る ----------*/
CurrentShdrEx = &DmyShdrEx;
for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
CurrentShdrEx->next = OSAPI_MALLOC( sizeof(ElShdrEx));
CurrentShdrEx = (ElShdrEx*)(CurrentShdrEx->next);
OSAPI_CPUFILL8( CurrentShdrEx, 0, sizeof(ElShdrEx)); //ゼロクリア
/*デバッグ情報かどうかを判別してフラグをセット*/
if( i_elShdrIsDebug( elElfDesc, i) == TRUE) { /*デバッグ情報の場合*/
CurrentShdrEx->debug_flag = 1;
}else{ /*デバッグ情報でない場合*/
/*セクションヘッダをコピー*/
i_elGetShdr( elElfDesc, i, &(CurrentShdrEx->Shdr));
CurrentShdrEx->debug_flag = 0;
}
}
CurrentShdrEx->next = NULL;
elElfDesc->ShdrEx = DmyShdrEx.next;
/*--------------------------------------------*/
/*---------- 全セクションを調べてコピーする ----------*/
PRINTDEBUG( "\nLoad to RAM:\n");
for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
/**/
CurrentShdrEx = i_elGetShdrExfromList( elElfDesc->ShdrEx, i);
// PRINTDEBUG( "section:%d sh_flag=0x%x\n", i, CurrentShdrEx->Shdr.sh_flags);
// PRINTDEBUG( "section:%d sh_type=0x%x\n", i, CurrentShdrEx->Shdr.sh_type);
if( CurrentShdrEx->debug_flag == 1) { /*デバッグ情報の場合*/
PRINTDEBUG( "skip debug-section %02x\n", i);
}else{ /*デバッグ情報でない場合*/
/* .text section */
if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_EXECINSTR))&&
(CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
//メモリにコピー
CurrentShdrEx->loaded_adr = (u32)
i_elCopySectionToBuffer( elElfDesc, &(CurrentShdrEx->Shdr));
}
/* .data, .data1 section (初期化済みデータ) */
else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
(CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
//メモリにコピー
CurrentShdrEx->loaded_adr = (u32)
i_elCopySectionToBuffer( elElfDesc, &(CurrentShdrEx->Shdr));
}
/* .bss section */
else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
(CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
//コピーしない
CurrentShdrEx->loaded_adr = (u32)
i_elAllocSectionToBuffer( elElfDesc, &(CurrentShdrEx->Shdr));
}
/* .rodata, .rodata1 section */
else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
(CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
//メモリにコピー
CurrentShdrEx->loaded_adr = (u32)
i_elCopySectionToBuffer( elElfDesc, &(CurrentShdrEx->Shdr));
}
PRINTDEBUG( "section %02x relocated at %08x\n",
i, CurrentShdrEx->loaded_adr);
}
}
/* コピー終了後 */
elElfDesc->process = EL_COPIED;
/*----------------------------------------------------*/
/*---------- グローバルシンボルの公開とローカルシンボルの再配置 ----------*/
PRINTDEBUG( "\nRelocate Symbols:\n");
for( i=0; i<(elElfDesc->CurrentEhdr.e_shnum); i++) {
/**/
CurrentShdrEx = i_elGetShdrExfromList( elElfDesc->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { /*デバッグ情報の場合*/
}else{ /*デバッグ情報でない場合*/
if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
/*リロケート*/
InfoShdrEx = i_elGetShdrExfromList( elElfDesc->ShdrEx,
CurrentShdrEx->Shdr.sh_info);
if( InfoShdrEx->loaded_adr != 0) { //対象セクションがロードされていれば内部を再配置
i_elRelocateSym( elElfDesc, i);
}
#if (DEBUG_PRINT_ON == 1)
num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
(CurrentShdrEx->Shdr.sh_entsize);
PRINTDEBUG( "num of REL = %x\n", num_of_entry);
PRINTDEBUG( "Section Header Info.\n");
PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
offset = 0;
for( j=0; j<num_of_entry; j++) {
i_elGetSent( elElfDesc, i, &(elElfDesc->Rel), offset, sizeof(Elf32_Rel));
i_elGetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
i_elGetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
(u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rel.r_info)), sizeof(Elf32_Sym));
i_elGetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
PRINTDEBUG( "%08x ", elElfDesc->Rel.r_offset);
PRINTDEBUG( "%08x ", elElfDesc->Rel.r_info);
PRINTDEBUG( " ");
PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
PRINTDEBUG( sym_str);
PRINTDEBUG( "\n");
/*次のエントリへ*/
offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
}
#endif
}
else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
/*リロケート*/
InfoShdrEx = i_elGetShdrExfromList( elElfDesc->ShdrEx,
CurrentShdrEx->Shdr.sh_info);
if( InfoShdrEx->loaded_adr != 0) { //対象セクションがロードされていれば内部を再配置
i_elRelocateSym( elElfDesc, i);
}
#if (DEBUG_PRINT_ON == 1)
num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
(CurrentShdrEx->Shdr.sh_entsize);
PRINTDEBUG( "num of RELA = %x\n", num_of_entry);
PRINTDEBUG( "Section Header Info.\n");
PRINTDEBUG( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
PRINTDEBUG( "info : %x\n", CurrentShdrEx->Shdr.sh_info);
PRINTDEBUG( " Offset Info Type Sym.Value Sym.Name\n");
offset = 0;
for( j=0; j<num_of_entry; j++) {
i_elGetSent( elElfDesc, i, &(elElfDesc->Rela), offset, sizeof(Elf32_Rel));
i_elGetShdr( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->SymShdr));
i_elGetSent( elElfDesc, CurrentShdrEx->Shdr.sh_link, &(elElfDesc->Sym),
(u32)(elElfDesc->SymShdr.sh_entsize * ELF32_R_SYM( elElfDesc->Rela.r_info)), sizeof(Elf32_Sym));
i_elGetStrAdr( elElfDesc, elElfDesc->SymShdr.sh_link, elElfDesc->Sym.st_name, sym_str, 128);
PRINTDEBUG( "%08x ", elElfDesc->Rela.r_offset);
PRINTDEBUG( "%08x ", elElfDesc->Rela.r_info);
PRINTDEBUG( " ");
PRINTDEBUG( "%08x ", elElfDesc->Sym.st_value);
PRINTDEBUG( sym_str);
PRINTDEBUG( "\n");
/*次のエントリへ*/
offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
}
#endif
}
else if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
/*グローバルシンボルをアドレステーブルに登録*/
i_elGoPublicGlobalSym( elElfDesc, i);
}
}
}
/*i_elRelocateSymやi_elGoPublicGlobalSym内で作成&使い回したシンボルリストを開放*/
i_elFreeSymList( elElfDesc);
/*------- ElShdrExのリストを解放する -------*/
CurrentShdrEx = elElfDesc->ShdrEx;
if( CurrentShdrEx) {
while( CurrentShdrEx->next != NULL) {
FwdShdrEx = CurrentShdrEx;
CurrentShdrEx = CurrentShdrEx->next;
OSAPI_FREE( FwdShdrEx);
}
elElfDesc->ShdrEx = NULL;
}
/*-----------------------------------------*/
/*RAM上のDLLが呼ばれる前にキャッシュをフラッシュ*/
#if (TARGET_ARM_V5 == 1)
OSAPI_FLUSHCACHEALL();
OSAPI_WAITCACHEBUF();
#endif
return (elElfDesc->process);
}
/*------------------------------------------------------
使
-----------------------------------------------------*/
u16 elResolveAllLibrary( ElDesc* elElfDesc)
{
ElAdrEntry* AdrEnt;
ElUnresolvedEntry* UnrEnt;
ElUnresolvedEntry* CurrentUnrEnt;
ElUnresolvedEntry* FwdUnrEnt;
BOOL ret_val;
UnrEnt = ELUnrEntStart;
PRINTDEBUG( "\nResolve all symbols:\n");
while( UnrEnt != NULL) {
AdrEnt = elGetAdrEntry( UnrEnt->sym_str); /*アドレステーブルから検索*/
if( AdrEnt) { /*アドレステーブルから見つかった場合*/
UnrEnt->S_ = (u32)(AdrEnt->adr);
UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
PRINTDEBUG( "\n symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
ret_val = i_elDoRelocate( elElfDesc, UnrEnt); /*シンボル解決*/
if( ret_val == FALSE) {
return EL_FAILED; //osPanicの方がいい?
}else{
UnrEnt->remove_flag = 1; /*解決したというマーキング*/
}
}else{ /*アドレステーブルから見つからなかった場合*/
PRINTDEBUG( "\n ERROR! cannot find symbol : %s\n\n", UnrEnt->sym_str);
return EL_FAILED; //osPanicの方がいい?
}
UnrEnt = UnrEnt->next; /*次の未解決エントリへ*/
}
/*TODO:ここで解決できなかったUnrEntエントリだけ削除するべき*/
/*--- ElUnresolvedEntryのリストを解放する ---*/
CurrentUnrEnt = ELUnrEntStart;
// if( CurrentUnrEnt) {
while( CurrentUnrEnt != NULL) {
FwdUnrEnt = CurrentUnrEnt;
CurrentUnrEnt = CurrentUnrEnt->next;
OSAPI_FREE( FwdUnrEnt->sym_str); //シンボル名文字列
OSAPI_FREE( FwdUnrEnt); //構造体自身
}
ELUnrEntStart = NULL;
// }
/*-------------------------------------------*/
/*ベニヤのリンクリストを開放*/
i_elFreeVenTbl();
/*RAM上のDLLが呼ばれる前にキャッシュをフラッシュ*/
#if (TARGET_ARM_V5 == 1)
OSAPI_FLUSHCACHEALL();
OSAPI_WAITCACHEBUF();
#endif
return EL_RELOCATED;
}
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL elRemoveAdrEntry( ElAdrEntry* AdrEnt)
{
ElAdrEntry DmyAdrEnt;
ElAdrEntry* CurrentAdrEnt;
DmyAdrEnt.next = ELAdrEntStart;
CurrentAdrEnt = &DmyAdrEnt;
while( CurrentAdrEnt->next != AdrEnt) {
if( CurrentAdrEnt->next == NULL) {
return FALSE;
}else{
CurrentAdrEnt = (ElAdrEntry*)CurrentAdrEnt->next;
}
}
/*リンクリストの繋ぎ直し*/
CurrentAdrEnt->next = AdrEnt->next;
ELAdrEntStart = DmyAdrEnt.next;
/*開放*/
OSAPI_FREE( AdrEnt);
return TRUE;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void elAddAdrEntry( ElAdrEntry* AdrEnt)
{
ElAdrEntry DmyAdrEnt;
ElAdrEntry* CurrentAdrEnt;
if( !ELAdrEntStart) {
ELAdrEntStart = AdrEnt;
}else{
DmyAdrEnt.next = ELAdrEntStart;
CurrentAdrEnt = &DmyAdrEnt;
while( CurrentAdrEnt->next != NULL) {
CurrentAdrEnt = (ElAdrEntry*)CurrentAdrEnt->next;
}
CurrentAdrEnt->next = (void*)AdrEnt;
}
AdrEnt->next = NULL;
}
/*------------------------------------------------------
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
__declspec(weak) void elAddStaticSym( void)
#else
SDK_WEAK_SYMBOL void elAddStaticSym( void)
#endif
{
PRINTDEBUG( "please link file which is generated by \"makelst\".\n");
while( 1) {};
}
/*------------------------------------------------------
-----------------------------------------------------*/
ElAdrEntry* elGetAdrEntry( const char* ent_name)
{
ElAdrEntry* CurrentAdrEnt;
CurrentAdrEnt = ELAdrEntStart;
if( CurrentAdrEnt == NULL) {
return NULL;
}
while( OSAPI_STRCMP( CurrentAdrEnt->name, ent_name) != 0) {
CurrentAdrEnt = (ElAdrEntry*)CurrentAdrEnt->next;
if( CurrentAdrEnt == NULL) {
break;
}
}
return CurrentAdrEnt;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void* elGetGlobalAdr( const char* ent_name)
{
u32 adr;
ElAdrEntry* CurrentAdrEnt;
CurrentAdrEnt = elGetAdrEntry( ent_name);
if( CurrentAdrEnt) {
if( CurrentAdrEnt->thumb_flag) {
adr = (u32)(CurrentAdrEnt->adr) + 1;
}else{
adr = (u32)(CurrentAdrEnt->adr);
}
}else{
adr = 0;
}
return (void*)(adr);
}
/*------------------------------------------------------
-----------------------------------------------------*/
#if 0
void* elFreeAdrTbl( void)
{
ElAdrEntry* FwdAdrEnt;
ElAdrEntry* CurrentAdrEnt;
/*--- ElAdrEntryのリストを解放する ---*/
CurrentAdrEnt = ELAdrEntStart;
if( CurrentAdrEnt) {
while( CurrentAdrEnt->next != NULL) {
FwdAdrEnt = CurrentAdrEnt;
CurrentAdrEnt = CurrentAdrEnt->next;
OSAPI_FREE( FwdAdrEnt->name); //シンボル名文字列
OSAPI_FREE( FwdAdrEnt); //構造体自身
}
ELAdrEntStart = NULL;
}
/*------------------------------------*/
return NULL;
}
#endif
/*------------------------------------------------------
ELFオブジェクトからデータを読み出すスタブ
-----------------------------------------------------*/
static void i_elReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
{
#if (TARGET_OS_NITRO == 1)
FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET);
FS_ReadFile( file_struct, buf, (s32)(size));
#else
fsLseek( (int)file_struct, (s32)(file_offset), SEEK_SET);
fsRead( (int)file_struct, buf, (s32)(size));
#endif
}
static void i_elReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
{
OSAPI_CPUCOPY8( (void*)(file_base + file_offset),
buf,
size);
}
//#if (TARGET_OS_NITRO == 1)
//#else
static void i_elReadUsr( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
{
i_elReadImage( file_offset, buf, size);
}
//#endif

View File

@ -0,0 +1,237 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: elf_loader.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef _ELF_LOADER_H_
#define _ELF_LOADER_H_
#include "el_config.h"
#if (TARGET_OS_NITRO == 1)
#include <nitro/fs.h>
#else
#include <ctr.h>
#include <stdio.h>
#endif
#include "elf.h"
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------
()
-----------------------------------------------------*/
typedef struct {
void* next;
u16 index;
u16 debug_flag; /*0:デバッグ情報でない、1:デバッグ情報*/
u32 loaded_adr;
u32 alloc_adr;
u32 loaded_size;
Elf32_Shdr Shdr;
}ElShdrEx;
/*------------------------------------------------------
()
-----------------------------------------------------*/
typedef struct {
void* next;
u16 debug_flag; /*0:デバッグ情報でない、1:デバッグ情報*/
u16 thumb_flag;
u32 relocation_val;
Elf32_Sym Sym;
}ElSymEx;
/*------------------------------------------------------
(i_elDoRelocateで使用)
-----------------------------------------------------*/
typedef struct {
void* next;
u32 adr; /* ベニヤコードの先頭アドレス */
u32 data; /* ベニヤのリテラルプールに格納されている飛び先のアドレス値 */
}ElVeneer;
/*------------------------------------------------------
ELFオブジェクトの管理
-----------------------------------------------------*/
typedef void (*i_elReadFunc)( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
typedef struct {
void* ar_head; /* ARまたはELFファイルの先頭アドレス */
void* elf_offset; /* ELFオブジェクトの先頭へのオフセット */
void* buf_current; /* Loader作業用 */
u16 shentsize; /* 1セクションヘッダのサイズ */
u16 process; /* 再配置状況 */
ElShdrEx* ShdrEx; /* ShdrExリストの先頭 */
Elf32_Ehdr CurrentEhdr; /* ELFヘッダ */
Elf32_Rel Rel; /* 再配置エントリ */
Elf32_Rela Rela;
Elf32_Sym Sym; /* シンボルエントリ */
Elf32_Shdr SymShdr;
ElSymEx* SymEx; /* SymExリストの先頭非デバッグシンボルのみ繋がる */
ElSymEx** SymExTbl; /* SymExアドレスのテーブル全シンボル数ぶん*/
u32 SymExTarget; /* SymExリストを構築したシンボルセクションのセクション番号 */
ElVeneer* VeneerEx; /* ベニヤのリンクリスト */
i_elReadFunc i_elReadStub; /* リードスタブ関数 */
void* FileStruct; /* ファイル構造体 */
u32 entry_adr; /* エントリアドレス */
}ElDesc;
/*------------------------------------------------------
-----------------------------------------------------*/
typedef struct {
void* next; /*次のアドレスエントリ*/
char* name; /*文字列*/
void* adr; /*アドレス*/
u16 func_flag; /*0:データ、1:関数*/
u16 thumb_flag; /*0:armコード、1:thumbコード*/
}ElAdrEntry;
/*------------------------------------------------------
S_ = AdrEntry.adr;
T_ = (u32)(AdrEntry.thumb_flag);
-----------------------------------------------------*/
typedef struct {
void* next; /*次のエントリ*/
char* sym_str; /*未解決の外部参照シンボル名*/
u32 r_type; /*リロケーションタイプELF32_R_TYPE( Rela.r_info)*/
u32 S_; /*未解決の外部参照シンボルアドレス*/
s32 A_; /*解決済み*/
u32 P_; /*解決済み*/
u32 T_; /*未解決の外部参照シンボルのARM/Thumbフラグ*/
u32 sh_type; /*SHT_REL or SHT_RELA*/
u32 remove_flag; /*解決したときにセットする(消しても良いことを識別する)フラグ*/
}ElUnresolvedEntry;
/* ElDesc の process値 */
#define EL_FAILED 0x00
#define EL_INITIALIZED 0x5A
#define EL_COPIED 0xF0
#define EL_RELOCATED 0xF1
/* typedef */
//#if (TARGET_OS_NITRO == 1)
//#else
typedef void *(*ElAlloc)(size_t size);
typedef void (*ElFree)(void* ptr);
typedef u32 (*ElReadImage)( u32 offset, void* buf, u32 size);
//#endif
/*---------------------------------------------------------
ELFオブジェクトのサイズを求める
--------------------------------------------------------*/
u32 elGetElfSize( const void* buf);
/*------------------------------------------------------
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
void elInit( void);
#else
void elInit( ElAlloc alloc, ElFree free);
#endif
/*------------------------------------------------------
ElDesc構造体を初期化する
-----------------------------------------------------*/
BOOL elInitDesc( ElDesc* elElfDesc);
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをファイルからバッファに再配置する
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
u16 elLoadLibraryfromFile( ElDesc* elElfDesc, FSFile* ObjFile, void* buf);
#else
u16 elLoadLibraryfromFile( ElDesc* elElfDesc, int ObjFile, void* buf);
#endif
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをユーザのリードAPIを通して再配置する
-----------------------------------------------------*/
#if (TARGET_OS_NITRO == 1)
#else
u16 elLoadLibrary( ElDesc* elElfDesc, ElReadImage readfunc, u32 len, void* buf);
#endif
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをメモリからバッファに再配置する
-----------------------------------------------------*/
u16 elLoadLibraryfromMem( ElDesc* elElfDesc, void* obj_image, u32 obj_len, void* buf);
/*------------------------------------------------------
使
-----------------------------------------------------*/
u16 elResolveAllLibrary( ElDesc* elElfDesc);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL elRemoveAdrEntry( ElAdrEntry* AdrEnt);
/*------------------------------------------------------
-----------------------------------------------------*/
void elAddAdrEntry( ElAdrEntry* AdrEnt);
/*------------------------------------------------------
ELライブラリ内でWEAKシンボルとして定義されており
makelstが生成したファイルの定義で上書きされる
-----------------------------------------------------*/
void elAddStaticSym( void);
/*------------------------------------------------------
-----------------------------------------------------*/
ElAdrEntry* elGetAdrEntry( const char* ent_name);
/*------------------------------------------------------
-----------------------------------------------------*/
void* elGetGlobalAdr( const char* ent_name);
/*他に必要そうな関数*/
//ロードに必要なメモリのバイト数を算出する関数
//elFreeLibrary
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /*_ELF_LOADER_H_*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: loader_subset.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef _LOADER_SUBSET_H_
#define _LOADER_SUBSET_H_
#include "elf.h"
#include "elf_loader.h"
/*------------------------------------------------------
start :
data :
-----------------------------------------------------*/
void* i_elCopyVeneerToBuffer( ElDesc* elElfDesc, u32 start, u32 data, s32 threshold);
/*------------------------------------------------------
start :
data :
threshold : 使
-----------------------------------------------------*/
void* i_elCopyV4tVeneerToBuffer( ElDesc* elElfDesc, u32 start, u32 data, s32 threshold);
/*------------------------------------------------------
-----------------------------------------------------*/
void* i_elCopySegmentToBuffer( ElDesc* elElfDesc, Elf32_Phdr* Phdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void* i_elCopySectionToBuffer( ElDesc* elElfDesc, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void* i_elAllocSectionToBuffer( ElDesc* elElfDesc, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elGetPhdr( ElDesc* elElfDesc, u32 index, Elf32_Phdr* Phdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elGetShdr( ElDesc* elElfDesc, u32 index, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elGetSent( ElDesc* elElfDesc, u32 index, void* entry_buf, u32 offset, u32 size);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elGetEntry( ElDesc* elElfDesc, Elf32_Shdr* Shdr, u32 index, void* entry_buf);
/*------------------------------------------------------
STRセクションヘッダの指定インデックスの文字列を取得する
-----------------------------------------------------*/
void i_elGetStrAdr( ElDesc* elElfDesc, u32 strsh_index, u32 ent_index, char* str, u32 len);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elRelocateSym( ElDesc* elElfDesc, u32 relsh_index);
/*------------------------------------------------------
-----------------------------------------------------*/
void i_elGoPublicGlobalSym( ElDesc* elElfDesc, u32 symtblsh_index);
/*------------------------------------------------------
i_elRelocateSymやi_elGoPublicGlobalSymの中で作成したシンボルリストを
APIを呼んでください
-----------------------------------------------------*/
void i_elFreeSymList( ElDesc* elElfDesc);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL i_elDoRelocate( ElDesc* elElfDesc, ElUnresolvedEntry* UnresolvedInfo);
/*------------------------------------------------------
ElSymExを取り出す
-----------------------------------------------------*/
//ElSymEx* i_elGetSymExfromList( ElSymEx* SymExStart, u32 index);
/*------------------------------------------------------
ElShdrExを取り出す
-----------------------------------------------------*/
ElShdrEx* i_elGetShdrExfromList( ElShdrEx* ShdrExStart, u32 index);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL i_elShdrIsDebug( ElDesc* elElfDesc, u32 index);
/*------------------------------------------------------
elElfDescのSymExテーブルを調べ
 ARMかTHUMBかを判定する
-----------------------------------------------------*/
u32 i_elCodeIsThumb( ElDesc* elElfDesc, u16 sh_index, u32 offset);
/*---------------------------------------------------------
--------------------------------------------------------*/
//void i_elUnresolvedInfoInit( ElUnresolvedEntry* UnresolvedInfo);
/*---------------------------------------------------------
--------------------------------------------------------*/
//void i_elAddUnresolvedEntry( ElUnresolvedEntry* UnrEnt);
void* i_elFreeVenTbl( void);
#endif /*_LOADER_SUBSET_H_*/

30
build/tests/el/Makefile Normal file
View File

@ -0,0 +1,30 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - tests - camera
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = el-1 \
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,54 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - CAMERA - demos - camera-1
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
SUBDIRS =
LCFILE_SPEC = main.lsf
#----------------------------------------------------------------------------
#TWL_CODEGEN = THUMB
TWL_PROC = ARM7
TARGET_BIN = main.axf
SRCS = sample1.c staticsymlist.c \
INCDIR += $(TWLSDK_ROOT)/include/twl \
$(TWLSDK_ROOT)/include/twl/devices/sdmc/ARM7 \
$(TWLSDK_ROOT)/include/twl/fatfs/ARM7 \
LLIBRARY_DIRS = $(TWLSDK_ROOT)/lib/ARM-BB/Release
LLIBRARIES = libfatfs_sp.twl.a \
libsd_sp.twl.a \
libel_sp.twl.a \
#SRCDIR = # using default
#LCFILE = # using default
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,40 @@
#----------------------------------------------------------------------------
# Project: TwlSDK - include
# File: ARM7-BB.lsf
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded insructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
#
# Nitro LCF SPEC FILE
#
Static $(TARGET_NAME)
{
Address 0x02004000
Library crt0.o
StackSize 1024 512
}
#Objects on MAIN RAM # nothing for elf2bin
#Autoload MAIN
#{
# Address 0x027e0000
# Library
#}
Autoload MAIN
{
Address 0x02020000
Object $(OBJS_STATIC)
Library $(LLIBS) $(GLIBS) $(CW_LIBS)
Object * (.wram)
}

View File

@ -0,0 +1,8 @@
#ifndef __AR_DL_TEST_H__
#define __AR_DL_TEST_H__
typedef void (*global_func_p)( void); //test_api1.c
typedef void (*g_func_p)( void); //test_api2.c
#endif /*__AR_DL_TEST_H__*/

View File

@ -0,0 +1,434 @@
#include "kernel_cfg.h"
#ifndef ATTRIBUTE_ALIGN
#define ATTRIBUTE_ALIGN(n) __attribute__ ((aligned(n)))
#endif
#define MAIN_TASK 1
#define TNUM_TSKID 32
#define TNUM_SEMID 32
#define TNUM_FLGID 32
#define TNUM_DTQID 32
#define TNUM_MBXID 32
#define TNUM_MPFID 32
#define TNUM_CYCID 32
#define TNUM_INHNO 32
#define TNUM_EXCNO 0
#define TNUM_MPLID 32
#define TNUM_ALMID 32
#define TNUM_ATTACHED_ISRNO 0
#define TNUM_ISRID 0
#define TNUM_MBFID 32
#define TNUM_MTXID 32
#define TNUM_PORID 0
#define TNUM_SVCNO 0
#if (CTR_DEF_SYSTEM_IOP == 1)
#define TSIZE_KERNEL_BUFFER (256*1024) /* 256KByte */
#define TSIZE_MAIN_STACK (32*1024) /* 32KByte */
#else
#define TSIZE_KERNEL_BUFFER (1024*1024) /* 1MByte */
#define TSIZE_MAIN_STACK (128*1024) /* 128KByte */
#endif
#define KERNEL_MAGIC_NUMBER 0x01234567
#if TKERNEL_PRVER >= 0x1040
#define CFG_INTHDR_ENTRY(inthdr) INTHDR_ENTRY(inthdr)
#define CFG_EXCHDR_ENTRY(exchdr) EXCHDR_ENTRY(exchdr)
#define CFG_INT_ENTRY(inthdr) INT_ENTRY(inthdr)
#define CFG_EXC_ENTRY(exchdr) EXC_ENTRY(exchdr)
#else
#error "This configuration file has no compatibility with TOPPERS/JSP rel 1.3 or earlier."
#endif
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define __ZERO(x,y) _declspec(naked) void y(void){}
#else
#define __ZERO(x,y) x y[1]
#endif
/* User specified include files*/
#include "sample1.h"
#include "hw_timer.h"
#include "timer.h"
#include "logtask.h"
/********* Object initializer [task] *********/
const ID _kernel_tmax_tskid = (TMIN_TSKID + TNUM_TSKID - 1);
static VP __stack_MAIN_TASK[TSIZE_MAIN_STACK/sizeof(VP)] ATTRIBUTE_ALIGN(32);
#define TNUM_TINIA (1)
const UINT _kernel_tnum_tinia = TNUM_TINIA;
const TINIA _kernel_tinia_table[TNUM_TINIA] = {
{MAIN_TASK, {0x00u | 0x02u, (VP_INT)(0), (FP)(main_task), INT_PRIORITY(5), sizeof(__stack_MAIN_TASK), __stack_MAIN_TASK, TA_NULL, (FP)(NULL)}}};
const ID _kernel_torder_table[TNUM_TINIA] = {1};
TCB _kernel_tcb_table[TNUM_TSKID] ATTRIBUTE_ALIGN(32);
TINIB _kernel_tinib_table[TNUM_TSKID];
#define TNUM_TSK_RID (0) /* —\ñIDÌ<E2809A>Ýè */
const UINT _kernel_tnum_trid = TNUM_TSK_RID;
__ZERO(const ID, _kernel_trid_table);
/************** Object initializer [semaphore] ****************/
//miya #define TNUM_SEMID 4
const ID _kernel_tmax_semid = (TMIN_SEMID + TNUM_SEMID - 1);
#define TNUM_SEMINIA (0)
const UINT _kernel_tnum_seminia = TNUM_SEMINIA;
__ZERO(const SEMINIA, _kernel_seminia_table);
SEMCB _kernel_semcb_table[TNUM_SEMID] ATTRIBUTE_ALIGN(32);
SEMINIB _kernel_seminib_table[TNUM_SEMID];
#define TNUM_SEM_RID (0)
const UINT _kernel_tnum_semrid = TNUM_SEM_RID;
__ZERO(const ID, _kernel_semrid_table);
/********** Object initializer [eventflag] *********/
// miya #define TNUM_FLGID 0
const ID _kernel_tmax_flgid = (TMIN_FLGID + TNUM_FLGID - 1);
#define TNUM_FLGINIA (0)
const UINT _kernel_tnum_flginia = TNUM_FLGINIA;
__ZERO(const FLGINIA,_kernel_flginia_table);
FLGCB _kernel_flgcb_table[TNUM_FLGID] ATTRIBUTE_ALIGN(32);
FLGINIB _kernel_flginib_table[TNUM_FLGID];
#define TNUM_FLG_RID (0)
const UINT _kernel_tnum_flgrid = TNUM_FLG_RID;
__ZERO(const ID, _kernel_flgrid_table);
/******** Object initializer [dataqueue] ********/
// miya #define TNUM_DTQID 0
const ID _kernel_tmax_dtqid = (TMIN_DTQID + TNUM_DTQID - 1);
#define TNUM_DTQINIA (0)
const UINT _kernel_tnum_dtqinia = TNUM_DTQINIA;
__ZERO(const DTQINIA,_kernel_dtqinia_table);
DTQCB _kernel_dtqcb_table[TNUM_DTQID] ATTRIBUTE_ALIGN(32);
DTQINIB _kernel_dtqinib_table[TNUM_DTQID];
#define TNUM_DTQ_RID (0)
const UINT _kernel_tnum_dtqrid = TNUM_DTQ_RID;
__ZERO(const ID, _kernel_dtqrid_table);
/******** Object initializer [mailbox] ********/
// miya #define TNUM_MBXID 0
const ID _kernel_tmax_mbxid = (TMIN_MBXID + TNUM_MBXID - 1);
#define TNUM_MBXINIA (0)
const UINT _kernel_tnum_mbxinia = TNUM_MBXINIA;
__ZERO(const MBXINIA,_kernel_mbxinia_table);
MBXCB _kernel_mbxcb_table[TNUM_MBXID] ATTRIBUTE_ALIGN(32);
MBXINIB _kernel_mbxinib_table[TNUM_MBXID];
#define TNUM_MBX_RID (0)
const UINT _kernel_tnum_mbxrid = TNUM_MBX_RID;
__ZERO(const ID, _kernel_mbxrid_table);
/******** Object initializer [mempfix] *******/
// miya #define TNUM_MPFID 0
const ID _kernel_tmax_mpfid = (TMIN_MPFID + TNUM_MPFID - 1);
#define TNUM_MPFINIA (0)
const UINT _kernel_tnum_mpfinia = TNUM_MPFINIA;
__ZERO(const MPFINIA,_kernel_mpfinia_table);
MPFCB _kernel_mpfcb_table[TNUM_MPFID] ATTRIBUTE_ALIGN(32);
MPFINIB _kernel_mpfinib_table[TNUM_MPFID];
#define TNUM_MPF_RID (0)
const UINT _kernel_tnum_mpfrid = TNUM_MPF_RID;
__ZERO(const ID, _kernel_mpfrid_table);
/************* Object initializer [cyclic] ***********/
// miya #define TNUM_CYCID 1
const ID _kernel_tmax_cycid = (TMIN_CYCID + TNUM_CYCID - 1);
#define TNUM_CYCINIA (0)
const UINT _kernel_tnum_cycinia = TNUM_CYCINIA;
__ZERO(const CYCINIA, _kernel_cycinia_table);
CYCCB _kernel_cyccb_table[TNUM_CYCID] ATTRIBUTE_ALIGN(32);
CYCINIB _kernel_cycinib_table[TNUM_CYCID];
#define TNUM_CYC_RID (0)
const UINT _kernel_tnum_cycrid = TNUM_CYC_RID;
__ZERO(const ID, _kernel_cycrid_table);
/******* Object initializer [interrupt] *********/
// miya #define TNUM_INHNO 1
const UINT _kernel_tnum_inhno = TNUM_INHNO;
#if (CTR_DEF_SYSTEM_IOP == 1)
CFG_INTHDR_ENTRY(timer_handler);
const INHINIB _kernel_inhinib_table[TNUM_INHNO] = {
{OS_INTR_ID_TIMER1,0,(FP)CFG_INT_ENTRY(timer_handler)}};
#else
__ZERO(const INHINIB, _kernel_inhinib_table);
#endif
/******** Object initializer [exception] **********/
/********** Object initializer [mempvar] ***********/
// miya #define TNUM_MPLID 0
const ID _kernel_tmax_mplid = (TMIN_MPLID + TNUM_MPLID - 1);
#define TNUM_MPLINIA (0)
const UINT _kernel_tnum_mplinia = TNUM_MPLINIA;
__ZERO(const MPLINIA,_kernel_mplinia_table);
MPLCB _kernel_mplcb_table[TNUM_MPLID] ATTRIBUTE_ALIGN(32);
MPLINIB _kernel_mplinib_table[TNUM_MPLID];
#define TNUM_MPL_RID (0)
const UINT _kernel_tnum_mplrid = TNUM_MPL_RID;
__ZERO(const ID, _kernel_mplrid_table);
/******* Object initializer [alarm] ********/
// miya #define TNUM_ALMID 0
const ID _kernel_tmax_almid = (TMIN_ALMID + TNUM_ALMID - 1);
#define TNUM_ALMINIA (0)
const UINT _kernel_tnum_alminia = TNUM_ALMINIA;
__ZERO(const ALMINIA,_kernel_alminia_table);
__ZERO(ALMCB, _kernel_almcb_table) ATTRIBUTE_ALIGN(32);
__ZERO(ALMINIB, _kernel_alminib_table);
#define TNUM_ALM_RID (0)
const UINT _kernel_tnum_almrid = TNUM_ALM_RID;
__ZERO(const ID, _kernel_almrid_table);
/* Overrun handler */
void (null)(ID tskid, VP_INT exinf);
FP _kernel_overrun_handler_function = (FP)NULL;
/******** Object initializer [attached_isr] ********/
// miya #define TNUM_ATTACHED_ISRNO 0
const UINT _kernel_tnum_attached_isrno = TNUM_ATTACHED_ISRNO;
__ZERO(const ATTACHED_ISRINIB,_kernel_attached_isrinib_table);
/******* Object initializer [interrupt_service] ********/
// miya #define TNUM_ISRID 0
const ID _kernel_tmax_isrid = (TMIN_ISRID + TNUM_ISRID - 1);
#define TNUM_ISRINIA (0)
const UINT _kernel_tnum_isrinia = TNUM_ISRINIA;
__ZERO(const ISRINIA,_kernel_isrinia_table);
__ZERO(ISRCB, _kernel_isrcb_table) ATTRIBUTE_ALIGN(32);
__ZERO(ISRINIB, _kernel_isrinib_table);
#define TNUM_ISR_RID (0)
const UINT _kernel_tnum_isrrid = TNUM_ISR_RID;
__ZERO(const ID, _kernel_isrrid_table);
/******** Object initializer [messagebuffer] ********/
// miya #define TNUM_MBFID 0
const ID _kernel_tmax_mbfid = (TMIN_MBFID + TNUM_MBFID - 1);
#define TNUM_MBFINIA (0)
const UINT _kernel_tnum_mbfinia = TNUM_MBFINIA;
__ZERO(const MBFINIA,_kernel_mbfinia_table);
MBFCB _kernel_mbfcb_table[TNUM_MBFID] ATTRIBUTE_ALIGN(32);
MBFINIB _kernel_mbfinib_table[TNUM_MBFID];
#define TNUM_MBF_RID (0)
const UINT _kernel_tnum_mbfrid = TNUM_MBF_RID;
__ZERO(const ID, _kernel_mbfrid_table);
/********* Object initializer [mutex] ************/
// miya #define TNUM_MTXID 0
const ID _kernel_tmax_mtxid = (TMIN_MTXID + TNUM_MTXID - 1);
#define TNUM_MTXINIA (0)
const UINT _kernel_tnum_mtxinia = TNUM_MTXINIA;
__ZERO(const MTXINIA,_kernel_mtxinia_table);
MTXCB _kernel_mtxcb_table[TNUM_MTXID] ATTRIBUTE_ALIGN(32);
MTXINIB _kernel_mtxinib_table[TNUM_MTXID];
#define TNUM_MTX_RID (0)
const UINT _kernel_tnum_mtxrid = TNUM_MTX_RID;
__ZERO(const ID, _kernel_mtxrid_table);
/******** Object initializer [rendezvous] ********/
// miya #define TNUM_PORID 0
const ID _kernel_tmax_porid = (TMIN_PORID + TNUM_PORID - 1);
#define TNUM_PORINIA (0)
const UINT _kernel_tnum_porinia = TNUM_PORINIA;
__ZERO(const PORINIA,_kernel_porinia_table);
__ZERO(PORCB, _kernel_porcb_table) ATTRIBUTE_ALIGN(32);
__ZERO(PORINIB, _kernel_porinib_table);
#define TNUM_POR_RID (0)
const UINT _kernel_tnum_porrid = TNUM_POR_RID;
__ZERO(const ID, _kernel_porrid_table);
/***** Object initializer [exservicecall] *****/
// miya #define TNUM_SVCNO 0
const UINT _kernel_tnum_svcno = TNUM_SVCNO;
__ZERO(const SVCINIB,_kernel_svcinib_table);
__ZERO(SVCCB, _kernel_svccb_table) ATTRIBUTE_ALIGN(32);
#define TNUM_SVC_RID (0)
const UINT _kernel_tnum_svcrid = TNUM_SVC_RID;
__ZERO(const ID, _kernel_svcrid_table);
/******* Kernel buffer ********/
// miya #define TSIZE_KERNEL_BUFFER (1024*1024)
VP __kernel_bufmgr_buffer[TSIZE_KERNEL_BUFFER/sizeof(VP)] ATTRIBUTE_ALIGN(32);
const SIZE __kernel_bufmgr_buffer_size = TSIZE_KERNEL_BUFFER;
TMEVTN _kernel_tmevt_heap[TNUM_TSKID + TNUM_CYCID + TNUM_ALMID];
/******** Variables for kernel checker ********/
#if (CTR_DEF_SYSTEM_IOP == 1)
static const UW _checker_magic_number = KERNEL_MAGIC_NUMBER;
#endif
/************************************************************/
// miya #define TNUM_EXCNO 0
const UINT _kernel_tnum_excno = TNUM_EXCNO;
__ZERO(const EXCINIB,_kernel_excinib_table);
/* Initialization handler */
void
_kernel_call_inirtn(void)
{
timer_initialize( (VP_INT)(0) );
// serial_initialize( (VP_INT)(0) );
}
void
_kernel_call_terrtn(void)
{
timer_terminate( (VP_INT)(0) );
}
/* Object initialization routine */
void
_kernel_object_initialize(void)
{
_kernel_bufmgr_initialize();
if( _kernel_tmax_tskid ) {
_kernel_task_initialize();
}
if( _kernel_tmax_semid ) {
_kernel_semaphore_initialize();
}
if( _kernel_tmax_flgid ) {
_kernel_eventflag_initialize();
}
if( _kernel_tmax_dtqid ) {
_kernel_dataqueue_initialize();
}
if( _kernel_tmax_mtxid ) {
_kernel_mutex_initialize();
}
if( _kernel_tmax_mbxid ) {
_kernel_mailbox_initialize();
}
if( _kernel_tmax_mpfid ) {
_kernel_mempfix_initialize();
}
if( _kernel_tmax_mplid ) {
_kernel_mempvar_initialize();
}
if( _kernel_tmax_cycid ) {
_kernel_cyclic_initialize();
}
if( _kernel_tmax_mbfid ) {
_kernel_messagebuffer_initialize();
}
if( _kernel_tmax_almid ) {
_kernel_alarm_initialize();
}
if( _kernel_tmax_porid ) {
_kernel_rendezvous_initialize();
}
#if 0
if( _kernel_tmax_isrid )
//_kernel_svchash_initialize();
task_overrun.c:overrun_initialize();
exception.c:exception_initialize();
interrupt.c:attached_isr_initialize();
interrupt.c:interrupt_service_initialize();
servicecall.c:_kernel_svchash_initialize();
servicecall.c:exservicecall_initialize();
#endif
#if (CTR_DEF_SYSTEM_IOP == 1)
_kernel_interrupt_initialize();
#endif
}

View File

@ -0,0 +1,208 @@
#include <twl_sp.h>
#include <el/elf_loader.h>
#include <devices/sdmc/ARM7/sdmc.h>
#include <fatfs/ARM7/rtfs.h>
#include "sample1.h"
#include "dlltest.h"
#define PRINTDEBUG( ...) ((void)0)
#define _DLL_LINK_DYNAMIC_ (1)
/*---------------------------------------------------------------------------*
static変数
*---------------------------------------------------------------------------*/
static u32 lib_buf[8192];
int fd;
u32 alloc_total_size = 0;
u32 alloc_max_size = 0;
#if (_DLL_LINK_DYNAMIC_ == 1)
global_func_p global_func;
g_func_p g_func;
#endif
/*---------------------------------------------------------------------------*
static関数
*---------------------------------------------------------------------------*/
static void display_entries( void);
u32 readlib( u32 offset, void* buf, u32 size);
int no_data;
//
//ストリームAPI用関数 (FILE構造体を使いたいなら必要)
//実際にはmalloc/freeなどが使えるようにするためのものなので、
//間違って使ったらサイズが足りなくなるかも
//
/*
#define MY_HEAP_SIZE (8192*6)//65536
static u8 myHeap[MY_HEAP_SIZE/sizeof(u8)] ATTRIBUTE_ALIGN(32);
static ID myMplID;
static void myInitHeap(void)
{
T_CMPL cmpl = { TA_TFIFO, MY_HEAP_SIZE, NULL };
myMplID = acre_mpl(&cmpl);
}
static void *myAlloc(size_t size)
{
void *ptr;
ER ercd = pget_mpl(myMplID, size, &ptr);
if (ercd == E_OK) {
T_RMPL rmpl;
ref_mpl(myMplID, &rmpl);
alloc_total_size += size;
if( alloc_total_size > alloc_max_size) {
alloc_max_size = alloc_total_size;
}
return ptr;
}
return NULL;
}
static void myFree(void *ptr)
{
rel_mpl(myMplID, ptr);
}
*/
static void *myAlloc(size_t size)
{
return( OS_Alloc( size));
}
static void myFree(void *ptr)
{
OS_Free( ptr);
}
int main(void)
{
extern void _uitron_start(void);
_uitron_start();
return 0;
}
/*
*
*/
void TwlSpMain( void)
{
ElDesc dll_desc;
u32 i;
u32 free_bytes, free_blocks, total_blocks;
u8 rslt;
u32 len;
int result;
// vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)) ;
PRINTDEBUG( "Sample program starts (exinf = %d).\n", (INT) exinf);
PRINTDEBUG( "printf test 0.03 = %f\n", 0.03);
/**/
PRINTDEBUG("Sample program starts.\n");
{
OSHeapHandle hh;
OS_SetSubPrivArenaLo( OS_InitAlloc( OS_ARENA_MAIN_SUBPRIV, OS_GetSubPrivArenaLo(), OS_GetSubPrivArenaHi(), 1));
hh = OS_CreateHeap( OS_ARENA_MAIN_SUBPRIV, OS_GetSubPrivArenaLo(), OS_GetSubPrivArenaHi());
OS_SetCurrentHeap( OS_ARENA_MAIN_SUBPRIV, hh);
if( rtfs_init() == FALSE) {
PRINTDEBUG( "rtfs_init failed.\n");
}else{
PRINTDEBUG( "rtfs_init success.\n");
}
}
OS_Alloc( 32);
/*SDドライバ初期化*/
result = sdmcInit( SDMC_NOUSE_DMA, NULL, NULL);
if( result != SDMC_NORMAL) {
PRINTDEBUG( "sdmcInit : failed\n");
while( 1) {};
}else{
PRINTDEBUG( "sdmcInit : success\n");
}
/*デバイスドライバの登録*/
if( sdmcRtfsAttach( 4) == FALSE) { //sdmcをEドライブにする
PRINTDEBUG( "sdmcRtfsAttach failed.\n");
}else{
PRINTDEBUG( "sdmcRtfsAttach success.\n");
}
if( !rtfs_pc_set_default_drive( (unsigned char*)"E:")) {
PRINTDEBUG( "pc_set_default_drive (E) failed\n");
while( 1){};
}
/*----------*/
fd = po_open( (byte*)"\\libdlltest.a", (PO_CREAT|PO_BINARY|PO_WRONLY), PS_IREAD);
if( fd < 0) {
PRINTDEBUG( "po_open failed.\n");
while( 1) {};
}
PRINTDEBUG( "po_open success.\n");
/*----------*/
elInit( myAlloc, myFree);//OS_Alloc, OS_Free);
PRINTDEBUG( "%s, %d\n", __FUNCTION__, __LINE__);
elInitDesc( &dll_desc);
PRINTDEBUG( "%s, %d\n", __FUNCTION__, __LINE__);
// elLoadLibraryfromFile( &dll_desc, fd, lib_buf);
len = po_lseek( fd, 0, PSEEK_END);
po_lseek( fd, 0, PSEEK_SET);
elLoadLibrary( &dll_desc, (ElReadImage)readlib, len, lib_buf);
PRINTDEBUG( "%s, %d\n", __FUNCTION__, __LINE__);
PRINTDEBUG( "alloc size : 0x%x\n", alloc_max_size);
elAddStaticSym();
PRINTDEBUG( "%s, %d\n", __FUNCTION__, __LINE__);
elResolveAllLibrary( &dll_desc);
PRINTDEBUG( "%s, %d\n", __FUNCTION__, __LINE__);
#if (_DLL_LINK_DYNAMIC_ == 1)
PRINTDEBUG( "LINK : dynamic\n");
global_func = (global_func_p)elGetGlobalAdr( "global_func\0");
PRINTDEBUG( "0x%x\n", global_func);
g_func = (g_func_p)elGetGlobalAdr( "g_func\0");
PRINTDEBUG( "0x%x\n", g_func);
#endif
PRINTDEBUG( "----- dll-func1 execution -----\n");
#if (_DLL_LINK_DYNAMIC_ == 1)
(*global_func)();
#else
global_func();
#endif
PRINTDEBUG( "----- dll-func2 execution -----\n");
#if (_DLL_LINK_DYNAMIC_ == 1)
(*g_func)();
#else
g_func();
#endif
PRINTDEBUG( "----- dll execution end -----\n");
PRINTDEBUG( "Sample program ends.\n");
// kernel_exit();
while( 1 ) {};
}
u32 readlib( u32 offset, void* buf, u32 size)
{
po_lseek( fd, offset, PSEEK_SET);
return( po_read( fd, buf, size));
}

View File

@ -0,0 +1,27 @@
/*
*
*/
#define MAIN_PRIORITY 5 /* メインタスクの優先度 */
/* HIGH_PRIORITY より高くすること */
#define HIGH_PRIORITY 9 /* 並列に実行されるタスクの優先度 */
#define MID_PRIORITY 10
#define LOW_PRIORITY 11
/*
* CPU例外ハンドラの起動方法など
*/
#ifndef STACK_SIZE
#define STACK_SIZE (8192) /* タスクのスタックサイズ */
#endif /* STACK_SIZE */
/*
*
*/
#ifndef _MACRO_ONLY
//extern void main_task(VP_INT exinf);
#endif /* _MACRO_ONLY */

View File

@ -0,0 +1,44 @@
/*This file generated automatically by the "makelst".*/
#ifndef __STATIC_SYM_LIST__
#define __STATIC_SYM_LIST__
#include <twl_sp.h>
#include <el/elf_loader.h>
/*--------------------------------
extern symbol
--------------------------------*/
extern int no_data;
extern void __aeabi_unwind_cpp_pr0( void);
//extern void Lib$$Request$$armlib( void);
/*--------------------------------
symbol structure
--------------------------------*/
ElAdrEntry AdrEnt_no_data = {
(void*)NULL,
(char*)"no_data\0",
(void*)&no_data,
0,
0,
};
/*
ElAdrEntry AdrEnt_Lib$$Request$$armlib = {
(void*)NULL,
(char*)"Lib$$Request$$armlib\0",
(void*)Lib$$Request$$armlib,
1,
0,
};*/
/*--------------------------------
API
--------------------------------*/
void elAddStaticSym( void)
{
elAddAdrEntry( &AdrEnt_no_data);
// elAddAdrEntry( &AdrEnt_Lib$$Request$$armlib);
}
#endif /*__STATIC_SYM_LIST__*/

View File

@ -0,0 +1,41 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - CAMERA - demos - camera-1
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: Makefile,v $
# $NoKeywords: $
#----------------------------------------------------------------------------
SUBDIRS =
#----------------------------------------------------------------------------
#TWL_CODEGEN = THUMB
TARGET_BIN = main.axf
SRCS = main.c
#SRCDIR = # using default
#LCFILE = # using default
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
do-build: $(TARGETS)
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====

View File

@ -0,0 +1,59 @@
/*---------------------------------------------------------------------------*
Project: TwlSDK - SND - demos - capture
File: main.c
Copyright 2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
$Log: main.c,v $
$NoKeywords: $
*---------------------------------------------------------------------------*/
#include <twl.h>
static void VBlankIntr(void);
/*---------------------------------------------------------------------------*
Name: TwlMain
Description: main
Arguments: None
Returns: None
*---------------------------------------------------------------------------*/
void TwlMain()
{
// 初期化
OS_Init();
GX_Init();
OS_InitTick();
// Vブランク割り込み設定
OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
(void)OS_EnableIrqMask(OS_IE_V_BLANK);
(void)OS_EnableIrq();
(void)GX_VBlankIntr(TRUE);
{
u16 bg_color = GX_RGB(31, 0, 0);
GX_LoadBGPltt(&bg_color, 0, sizeof(u16));
}
while (1)
{
OS_WaitVBlankIntr();
}
}
//--------------------------------------------------------------------------------
// Vブランク割り込み処理
//
void VBlankIntr(void)
{
OS_SetIrqCheckFlag(OS_IE_V_BLANK); // checking VBlank interrupt
}

View File

@ -0,0 +1,32 @@
#! make -f
#----------------------------------------------------------------------------
# Project: TwlSDK - build
# File: Makefile
#
# Copyright 2007 Nintendo. All rights reserved.
#
# These coded instructions, statements, and computer programs contain
# proprietary information of Nintendo of America Inc. and/or Nintendo
# Company Ltd., and are protected by Federal copyright law. They may
# not be disclosed to third parties or copied or duplicated in any form,
# in whole or in part, without the prior written consent of Nintendo.
#
# $Log: $
# $NoKeywords: $
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/commondefs
#----------------------------------------------------------------------------
SUBDIRS = \
ARM7 \
ARM9 \
#----------------------------------------------------------------------------
include $(TWLSDK_ROOT)/build/buildtools/modulerules
#===== End of Makefile =====