add makelst(tentative)

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@155 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
shirait 2007-07-02 09:42:44 +00:00
parent 9dd92e3eee
commit 0c34a21d35
15 changed files with 3552 additions and 0 deletions

48
tools/makelst/Makefile Normal file
View File

@ -0,0 +1,48 @@
#! make -f
#---------------------------------------------------------------------------
# Project: NitroSDK - tools - makelst
# File: Makefile
#
# 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 $(NITROSDK_ROOT)/build/buildtools/commondefs
TARGETS = makelst.exe
SOURCES_C = makelst.c arch.c elf.c loader_subset.c elf_loader.c searcharg.c
SOURCES = $(SOURCES_C)
OBJECTS = $(SOURCES_C:.c=.o)
HEADERS =
INSTALL_DIR = .
INSTALL_TARGETS = $(TARGETS)
LDIRT_CLEAN = $(OBJECTS) $(TARGETS)
include $(NITROSDK_ROOT)/build/buildtools/modulerules.x86
#----------------------------------------------------------------------------
# build
#----------------------------------------------------------------------------
do-build: $(TARGETS)
$(TARGETS): $(OBJECTS)
$(CC_X86) $+ -o $@
makelcf.o: makelcf.c makelcf.h version.h
version.h: $(SOURCES) $(HEADERS) $(MAKEFILE)
@for i in $^ ; \
do \
date -r $$i +'#define SDK_DATE_OF_LATEST_FILE %Y%m%dUL'; \
done | sort | tail -1 > $@

39
tools/makelst/arch.c Normal file
View File

@ -0,0 +1,39 @@
#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;
}

38
tools/makelst/arch.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef ARCH_H_
#define ARCH_H_
#include "types.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_*/

341
tools/makelst/elf.c Normal file
View File

@ -0,0 +1,341 @@
#include <string.h>
#include "types.h"
#include "elf.h"
#include "stdio.h"
#include "stdlib.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;
/* バッファにコピー */
//MI_CpuCopy8( (void*)file_ptr, ehdr->e_ident, EI_NIDENT);
memcpy( (void*)(ehdr->e_ident), (void*)file_ptr, 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ヘッダ表示 ----------*/
/* printf( "\nELF Header:\n");
file_ptr = load_elf32_half(&(ehdr->e_machine), file_ptr, endian);
printf("e_machine = %d\n",ehdr->e_machine);
file_ptr = load_elf32_word(&(ehdr->e_version), file_ptr, endian);
printf("e_version = %d\n",ehdr->e_version);
file_ptr = load_elf32_word(&(ehdr->e_entry), file_ptr, endian);
printf("e_entry(entry point) = 0x%08x\n",ehdr->e_entry);
file_ptr = load_elf32_word(&(ehdr->e_phoff), file_ptr, endian);
printf("e_phoff(program header offset) = 0x%08x\n",ehdr->e_phoff);
file_ptr = load_elf32_word(&(ehdr->e_shoff), file_ptr, endian);
printf("e_shoff(section header offset) = 0x%08x\n",ehdr->e_shoff);
file_ptr = load_elf32_word(&(ehdr->e_flags), file_ptr, endian);
printf("e_flags = 0x%08x\n",ehdr->e_flags);
if( ehdr->e_flags & EF_ARM_HASENTRY ) {
printf("has entry\n");
}
if( ehdr->e_flags & EF_ARM_SYMSARESORTED ) {
printf("symbols are sorted\n");
}
if( ehdr->e_flags & EF_ARM_DYNSYMSUSESEGIDX ) {
printf("dynamic symbols use segmnet index\n");
}
if( ehdr->e_flags & EF_ARM_MAPSYMSFIRST ) {
printf("map symbols first\n");
}
printf("EABI version %x \n", (ehdr->e_flags & EF_ARM_EABIMASK) >> 24 );
file_ptr = load_elf32_half(&(ehdr->e_ehsize), file_ptr, endian);
printf("e_ehsize = %d\n",ehdr->e_ehsize);
file_ptr = load_elf32_half(&(ehdr->e_phentsize), file_ptr, endian);
printf("e_phentsize = %d\n",ehdr->e_phentsize);
file_ptr = load_elf32_half(&(ehdr->e_phnum), file_ptr, endian);
printf("e_phnum = %d\n",ehdr->e_phnum);
file_ptr = load_elf32_half(&(ehdr->e_shentsize), file_ptr, endian);
printf("e_shentsize = %d\n",ehdr->e_shentsize);
file_ptr = load_elf32_half(&(ehdr->e_shnum), file_ptr, endian);
printf("e_shnum = %d\n",ehdr->e_shnum);
file_ptr = load_elf32_half(&(ehdr->e_shstrndx), file_ptr, endian);
printf("e_shstrndx(section index no. of the section header string table section = %d\n",ehdr->e_shstrndx);
printf( "\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;
}

412
tools/makelst/elf.h Normal file
View File

@ -0,0 +1,412 @@
#ifndef ELF_H_
#define ELF_H_
#include "types.h"
/*---------------------------------------------------------
--------------------------------------------------------*/
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;
/* */
enum {
PT_NULL, /* 使われないエントリで、他のメンバの値の意味は未定義 */
PT_LOAD, /* 実行時にロードされるセグメント */
PT_DYNAMIC, /* 動的構造体配列を保持するセグメント */
PT_INTERP, /* ファイルの解釈に使われるインタプリタのパスを保持するセグメント */
PT_NOTE, /* ファイルの解釈には使われない情報を保持するセグメント */
PT_SHLIB, /* 予約 */
PT_PHDR, /* プログラムヘッダテーブル(プログラムのメモリイメージの一部である場合のみ存在) */
PT_TLS, /* スレッド局所記憶領域のテンプレート */
PT_LOOS = 0x60000000,
/* OS固有のセマンティクスの為に予約された領域 */
PT_HIOS = 0x6fffffff,
PT_LOPROC = 0x70000000,
/* プロセッサ固有のセマンティクスの為に予約された領域 */
PT_HIPROC = 0x7fffffff
};
/*---------------------------------------------------------
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. */
/*セクションインデックス*/
//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_MW_SPECIFIC 14 /*NITROアプリで出てくる(例:OS_TPrintf)*/
#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_ */

775
tools/makelst/elf_loader.c Normal file
View File

@ -0,0 +1,775 @@
/*---------------------------------------------------------------------------*
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 <stdlib.h>
#include <string.h>
#include "types.h"
#include "elf.h"
#include "elf_loader.h"
#include "arch.h"
#include "loader_subset.h"
//OSHeapHandle EL_Heap;
ELAdrEntry* ELAdrEntStart = NULL;
ELUnresolvedEntry* ELUnrEntStart = NULL;
extern u16 dbg_print_flag;
extern u32 unresolved_table_block_flag;
#define MAKELST_DS_API " elAddAdrEntry" //DS上でアドレステーブルに追加するAPI関数名
extern char c_source_line_str[256];
extern FILE* CSourceFilep;
/*------------------------------------------------------
-----------------------------------------------------*/
// ELFオブジェクトまたはそのアーカイブをバッファに再配置する
u16 ELi_LoadLibrary( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf);
// ELFオブジェクトをバッファに再配置するコア関数
u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf);
// ELFオブジェクトからデータを読み出すスタブ関数
void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size);
/*---------------------------------------------------------
ELFオブジェクトのサイズを求める
buf : ELFイメージのアドレス
--------------------------------------------------------*/
u32 EL_GetElfSize( 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;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void EL_Init( void)
{
// void* heap_start;
printf( "\n");
/*--- メモリアロケーション関係の設定 ---*/
/* 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);*/
/*--------------------------------------*/
}
/*------------------------------------------------------
ELHandle構造体を初期化する
-----------------------------------------------------*/
BOOL EL_InitHandle( ELHandle* ElfHandle)
{
if( ElfHandle == NULL) { /*NULLチェック*/
return FALSE;
}
/*初期値の設定*/
ElfHandle->ShdrEx = NULL;
ElfHandle->SymEx = NULL;
ElfHandle->process = EL_INITIALIZED; /*フラグの設定*/
return TRUE;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
ElfHandle :
ObjFile : OBJファイルまたはアーカイブファイルの構造体
buf :
-----------------------------------------------------*/
u16 EL_LoadLibraryfromFile( ELHandle* ElfHandle, FILE* ObjFile, void* buf)
{
u16 result;
u32 len;
/*リード関数の設定*/
ElfHandle->ELi_ReadStub = ELi_ReadFile;
ElfHandle->FileStruct = ObjFile;
fseek( ObjFile, 0, SEEK_END);
len = ftell( ObjFile);
fseek( ObjFile, 0, SEEK_SET);
result = ELi_LoadLibrary( ElfHandle, NULL, len, buf);
return result;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
ElfHandle :
obj_image : OBJファイルまたはアーカイブファイルのRAM上イメージアドレス
buf :
-----------------------------------------------------*/
u16 EL_LoadLibraryfromMem( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf)
{
u16 result;
/*リード関数の設定*/
ElfHandle->ELi_ReadStub = ELi_ReadMem;
ElfHandle->FileStruct = NULL;
result = ELi_LoadLibrary( ElfHandle, obj_image, obj_len, buf);
return result;
}
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをバッファに再配置する
ElfHandle :
obj_image : OBJファイルまたはアーカイブファイルのRAM上イメージアドレス
buf :
-----------------------------------------------------*/
u16 ELi_LoadLibrary( ELHandle* ElfHandle, 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;
ElfHandle->ar_head = obj_image;
image_pointer = 0;
ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)obj_image, 0, 8); /*OBJの文字列を取得*/
/*--------------- アーカイブファイルの場合 ---------------*/
if( strncmp( OBJMAG, ARMAG, 8) == 0) {
arch_size = sizeof( ArchHdr);
image_pointer += 8; /*最初のエントリへ*/
ElfHandle->buf_current = buf;
while( image_pointer < obj_len) {
ElfHandle->ELi_ReadStub( OBJMAG, ElfHandle->FileStruct, (u32)(obj_image), (image_pointer+arch_size), 4); /*OBJの文字列を取得*/
if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
elf_num++;
result = ELi_LoadObject( ElfHandle, (void*)(image_pointer+arch_size), ElfHandle->buf_current);
if( result < all_result) { /*悪い結果のときだけall_resultに反映*/
all_result = result;
}
/*初期値の設定*/
ElfHandle->ShdrEx = NULL;
ElfHandle->SymEx = NULL;
ElfHandle->process = EL_INITIALIZED; /*フラグの設定*/
}else{
}
/*次のエントリへ*/
ElfHandle->ELi_ReadStub( &ArHdr, ElfHandle->FileStruct, (u32)(obj_image), image_pointer, arch_size);
image_pointer += arch_size + AR_GetEntrySize( &ArHdr);
}
}else{/*--------------- ELFファイルの場合 ---------------*/
if( strncmp( OBJMAG, ELFMAG, 4) == 0) {
elf_num++;
all_result = ELi_LoadObject( ElfHandle, 0, buf);
}
}
/*-------------------------------------------------------*/
if( elf_num) {
return all_result;
}else{
return EL_FAILED;
}
}
/*------------------------------------------------------
ELFオブジェクトをバッファに再配置する
ElfHandle :
obj_offset : OBJファイルのRAM上イメージアドレスからのオフセット
buf :
-----------------------------------------------------*/
u16 ELi_LoadObject( ELHandle* ElfHandle, void* obj_offset, void* buf)
{
u16 i, j;
u32 num_of_entry;
ELShdrEx* FwdShdrEx;
ELShdrEx* CurrentShdrEx;
ELShdrEx DmyShdrEx;
char sym_str[128]; //デバッグプリント用
u32 offset; //デバッグプリント用
/* ELHandleの初期化チェック */
if( ElfHandle->process != EL_INITIALIZED) {
return EL_FAILED;
}
/* バッファのNULLチェック */
if( buf == NULL) {
return EL_FAILED;
}
/* ELFヘッダの取得 */
ElfHandle->ELi_ReadStub( &(ElfHandle->CurrentEhdr), ElfHandle->FileStruct,
(u32)(ElfHandle->ar_head), (u32)(obj_offset), sizeof( Elf32_Ehdr));
/* セクションハンドル構築 */
ElfHandle->elf_offset = obj_offset;
ElfHandle->buf_current = buf;
ElfHandle->shentsize = ElfHandle->CurrentEhdr.e_shentsize;
/*---------- ELShdrExのリストを作る ----------*/
CurrentShdrEx = &DmyShdrEx;
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
CurrentShdrEx->next = (void*)(malloc( sizeof(ELShdrEx)));
CurrentShdrEx = (ELShdrEx*)(CurrentShdrEx->next);
memset( CurrentShdrEx, 0, sizeof(ELShdrEx)); //ゼロクリア
/*デバッグ情報かどうかを判別してフラグをセット*/
if( ELi_ShdrIsDebug( ElfHandle, i) == TRUE) { /*デバッグ情報の場合*/
CurrentShdrEx->debug_flag = 1;
}else{ /*デバッグ情報でない場合*/
/*セクションヘッダをコピー*/
ELi_GetShdr( ElfHandle, i, &(CurrentShdrEx->Shdr));
CurrentShdrEx->debug_flag = 0;
}
}
CurrentShdrEx->next = NULL;
ElfHandle->ShdrEx = DmyShdrEx.next;
/*--------------------------------------------*/
/*---------- 全セクションを調べてコピーする ----------*/
/* printf( "\nLoad to RAM:\n");
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
//
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { //デバッグ情報の場合
printf( "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)
ELi_CopySectionToBuffer( ElfHandle, &(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)
ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
}
// .bss section
else if( (CurrentShdrEx->Shdr.sh_flags == (SHF_ALLOC | SHF_WRITE))&&
(CurrentShdrEx->Shdr.sh_type == SHT_NOBITS)) {
//コピーしない
CurrentShdrEx->loaded_adr = (u32)
ELi_AllocSectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
}
// .rodata, .rodata1 section
else if( (CurrentShdrEx->Shdr.sh_flags == SHF_ALLOC)&&
(CurrentShdrEx->Shdr.sh_type == SHT_PROGBITS)) {
//メモリにコピー
CurrentShdrEx->loaded_adr = (u32)
ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
}
printf( "section %02x relocated at %08x\n",
i, CurrentShdrEx->loaded_adr);
}
}
// コピー終了後
ElfHandle->process = EL_COPIED;*/
/*----------------------------------------------------*/
/*---------- 再配置 ----------*/
if( unresolved_table_block_flag == 0) {
if( dbg_print_flag == 1) {
printf( "\nRelocate Symbols:\n");
}
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
/**/
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { /*デバッグ情報の場合*/
}else{ /*デバッグ情報でない場合*/
if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
(CurrentShdrEx->Shdr.sh_entsize);
if( dbg_print_flag == 1) {
printf( "num of REL = %x\n", (int)(num_of_entry));
printf( "Section Header Info.\n");
printf( "link : %x\n", (int)(CurrentShdrEx->Shdr.sh_link));
printf( "info : %x\n", (int)(CurrentShdrEx->Shdr.sh_info));
printf( " Offset Info Type Sym.Value Sym.Name\n");
}
offset = 0;
for( j=0; j<num_of_entry; j++) {
ELi_GetSent( ElfHandle, i, &(ElfHandle->Rel), offset, sizeof(Elf32_Rel));
ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
(u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rel.r_info)), sizeof(Elf32_Sym));
ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
if( dbg_print_flag == 1) {
printf( "%08x ", (int)(ElfHandle->Rel.r_offset));
printf( "%08x ", (int)(ElfHandle->Rel.r_info));
printf( " ");
printf( "%08x ", (int)(ElfHandle->Sym.st_value));
printf( sym_str);
printf( "\n");
}
/*次のエントリへ*/
offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
}
if( dbg_print_flag == 1) {
printf( "\n");
}
/*リロケート*/
ELi_RelocateSym( ElfHandle, i);
if( dbg_print_flag == 1) {
printf( "\n");
}
}
else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
num_of_entry = (CurrentShdrEx->Shdr.sh_size) /
(CurrentShdrEx->Shdr.sh_entsize);
if( dbg_print_flag == 1) {
printf( "num of RELA = %x\n", (int)(num_of_entry));
printf( "Section Header Info.\n");
printf( "link : %x\n", (int)(CurrentShdrEx->Shdr.sh_link));
printf( "info : %x\n", (int)(CurrentShdrEx->Shdr.sh_info));
printf( " Offset Info Type Sym.Value Sym.Name\n");
}
offset = 0;
for( j=0; j<num_of_entry; j++) {
ELi_GetSent( ElfHandle, i, &(ElfHandle->Rela), offset, sizeof(Elf32_Rel));
ELi_GetShdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->SymShdr));
ELi_GetSent( ElfHandle, CurrentShdrEx->Shdr.sh_link, &(ElfHandle->Sym),
(u32)(ElfHandle->SymShdr.sh_entsize * ELF32_R_SYM( ElfHandle->Rela.r_info)), sizeof(Elf32_Sym));
ELi_GetStrAdr( ElfHandle, ElfHandle->SymShdr.sh_link, ElfHandle->Sym.st_name, sym_str, 128);
if( dbg_print_flag == 1) {
printf( "%08x ", (int)(ElfHandle->Rela.r_offset));
printf( "%08x ", (int)(ElfHandle->Rela.r_info));
printf( " ");
printf( "%08x ", (int)(ElfHandle->Sym.st_value));
printf( sym_str);
printf( "\n");
}
/*次のエントリへ*/
offset += (u32)(CurrentShdrEx->Shdr.sh_entsize);
}
if( dbg_print_flag == 1) {
printf( "\n");
}
/*リロケート*/
ELi_RelocateSym( ElfHandle, i);
if( dbg_print_flag == 1) {
printf( "\n");
}
}
}
}
}else{ /*dllでなくてstaticモジュールの場合*/
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { /*デバッグ情報の場合*/
}else{
if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
ELi_DiscriminateGlobalSym( ElfHandle, i);
}
}
}
}
/*------- ELShdrExのリストを解放する -------*/
CurrentShdrEx = ElfHandle->ShdrEx;
if( CurrentShdrEx) {
while( CurrentShdrEx->next != NULL) {
FwdShdrEx = CurrentShdrEx;
CurrentShdrEx = CurrentShdrEx->next;
free( FwdShdrEx);
}
ElfHandle->ShdrEx = NULL;
}
/*-----------------------------------------*/
/*RAM上のDLLが呼ばれる前にキャッシュをフラッシュ*/
// DC_FlushAll();
// DC_WaitWriteBufferEmpty();
return (ElfHandle->process);
}
/*------------------------------------------------------
使
-----------------------------------------------------*/
u16 EL_ResolveAllLibrary( void)
{
ELAdrEntry* AdrEnt;
ELUnresolvedEntry* RemoveUnrEnt;
ELUnresolvedEntry* UnrEnt;
// ELUnresolvedEntry* CurrentUnrEnt;
// ELUnresolvedEntry* FwdUnrEnt;
// u32 relocation_val;
// ELAdrEntry AddAdrEnt;
char sym_str[128];
UnrEnt = ELUnrEntStart;
if( dbg_print_flag == 1) {
printf( "\nResolve all symbols:\n");
}
while( UnrEnt != NULL) {
if( UnrEnt->remove_flag == 0) {
AdrEnt = EL_GetAdrEntry( UnrEnt->sym_str); /*アドレステーブルから検索*/
if( AdrEnt) { /*アドレステーブルから見つかった場合*/
UnrEnt->S_ = (u32)(AdrEnt->adr);
UnrEnt->T_ = (u32)(AdrEnt->thumb_flag);
if( unresolved_table_block_flag == 0) {
if( dbg_print_flag == 1) {
printf( "\n symbol found %s : %8x\n", UnrEnt->sym_str, (int)(UnrEnt->S_));
}
UnrEnt->remove_flag = 1;
// ELi_RemoveUnresolvedEntry( UnrEnt); //解決したので未解決リストから削除
}else{
if( dbg_print_flag == 1) {
printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, (int)(UnrEnt->S_));
}
UnrEnt->AdrEnt = AdrEnt; //見つけたアドレスエントリをセット
UnrEnt->remove_flag = 2; //マーキングmakelstだけで使用する特別な値
strcpy( sym_str, UnrEnt->sym_str);
while( 1) {
RemoveUnrEnt = ELi_GetUnresolvedEntry( sym_str);
if( RemoveUnrEnt == NULL) {
break;
}else{
RemoveUnrEnt->remove_flag = 1;
}
}
}
/* relocation_val = ELi_DoRelocate( UnrEnt); //シンボル解決
if( !relocation_val) {
return EL_FAILED;
}*/
}else{ /*アドレステーブルから見つからなかった場合*/
if( unresolved_table_block_flag == 0) {
if( dbg_print_flag == 1) {
printf( "ERROR! cannot find symbol : %s\n", UnrEnt->sym_str);
}
}else{
if( dbg_print_flag == 1) {
printf( "ERROR! cannot find static symbol : %s\n", UnrEnt->sym_str);
}
}
/* AddAdrEnt.next = NULL;
AddAdrEnt.name = UnrEnt->sym_str;
AddAdrEnt.
EL_AddAdrEntry( */
// return EL_FAILED;
}
}
UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*次の未解決エントリへ*/
}
/*--- ELUnresolvedEntryのリストを解放する ---*/
/* CurrentUnrEnt = ELUnrEntStart;
if( CurrentUnrEnt) {
while( CurrentUnrEnt->next != NULL) {
FwdUnrEnt = CurrentUnrEnt;
CurrentUnrEnt = CurrentUnrEnt->next;
free( FwdUnrEnt->sym_str); //シンボル名文字列
free( FwdUnrEnt); //構造体自身
}
ELUnrEntStart = NULL;
}*/
/*-------------------------------------------*/
/*RAM上のDLLが呼ばれる前にキャッシュをフラッシュ*/
// DC_FlushAll();
// DC_WaitWriteBufferEmpty();
return EL_RELOCATED;
}
/*------------------------------------------------------
-----------------------------------------------------*/
u16 EL_ExtractStaticSym1( void)
{
// ELAdrEntry* AdrEnt;
// ELUnresolvedEntry* RemoveUnrEnt;
ELUnresolvedEntry* UnrEnt;
// ELUnresolvedEntry* CurrentUnrEnt;
// ELUnresolvedEntry* FwdUnrEnt;
// u32 relocation_val;
// ELAdrEntry AddAdrEnt;
char sym_str[256];
UnrEnt = ELUnrEntStart;
file_write( "/*--------------------------------\n", CSourceFilep);
file_write( " extern symbol\n", CSourceFilep);
file_write( " --------------------------------*/\n", CSourceFilep);
while( UnrEnt != NULL) {
if( UnrEnt->remove_flag == 2) {//マーキングmakelstだけで使用する特別な値
if( (UnrEnt->AdrEnt->func_flag) != STT_FUNC) {
memset( sym_str, 0, 128);
strcpy( sym_str, "extern u8 ");
strcat( sym_str, UnrEnt->sym_str);
strcat( sym_str, ";\n");
file_write( sym_str, CSourceFilep);
}
}
UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*次の未解決エントリへ*/
}
file_write( "\n\n", CSourceFilep);
file_write( "/*--------------------------------\n", CSourceFilep);
file_write( " symbol structure\n", CSourceFilep);
file_write( " --------------------------------*/\n", CSourceFilep);
UnrEnt = ELUnrEntStart;
while( UnrEnt != NULL) {
if( UnrEnt->remove_flag == 2) {//マーキングmakelstだけで使用する特別な値
memset( sym_str, 0, 128);
strcpy( sym_str, "ElAdrEntry AdrEnt_");
strcat( sym_str, UnrEnt->sym_str);
strcat( sym_str, " = {\n");
file_write( sym_str, CSourceFilep);
file_write( " (void*)NULL,\n", CSourceFilep);
strcpy( sym_str, " (char*)\"");
strcat( sym_str, UnrEnt->sym_str);
strcat( sym_str, "\\0\", \n");
file_write( sym_str, CSourceFilep);
if( (UnrEnt->AdrEnt->func_flag) == STT_FUNC) {
strcpy( sym_str, " (void*)");
}else{
strcpy( sym_str, " (void*)&");
}
strcat( sym_str, UnrEnt->sym_str);
strcat( sym_str, ",\n");
file_write( sym_str, CSourceFilep);
if( (UnrEnt->AdrEnt->func_flag) == 1) {
file_write( " 0,\n", CSourceFilep);
}else{
file_write( " 1,\n", CSourceFilep);
}
if( (UnrEnt->AdrEnt->thumb_flag) == 0) {
file_write( " 0,\n", CSourceFilep);
}else{
file_write( " 1,\n", CSourceFilep);
}
file_write( "};\n", CSourceFilep);
// printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
}
UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*次の未解決エントリへ*/
}
}
/*------------------------------------------------------
APIとして書き出す
-----------------------------------------------------*/
u16 EL_ExtractStaticSym2( void)
{
// ELAdrEntry* AdrEnt;
// ELUnresolvedEntry* RemoveUnrEnt;
ELUnresolvedEntry* UnrEnt;
// ELUnresolvedEntry* CurrentUnrEnt;
// ELUnresolvedEntry* FwdUnrEnt;
// u32 relocation_val;
// ELAdrEntry AddAdrEnt;
char sym_str[256];
UnrEnt = ELUnrEntStart;
while( UnrEnt != NULL) {
if( UnrEnt->remove_flag == 2) {//マーキングmakelstだけで使用する特別な値
memset( sym_str, 0, 128);
strcpy( sym_str, MAKELST_DS_API);
strcat( sym_str, "( &AdrEnt_");
strcat( sym_str, UnrEnt->sym_str);
strcat( sym_str, ");\n");
file_write( sym_str, CSourceFilep);
// printf( "\n static symbol found %s : %8x\n", UnrEnt->sym_str, UnrEnt->S_);
}
UnrEnt = (ELUnresolvedEntry*)(UnrEnt->next); /*次の未解決エントリへ*/
}
}
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL EL_RemoveAdrEntry( 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;
return TRUE;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void EL_AddAdrEntry( 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;
}
/*------------------------------------------------------
-----------------------------------------------------*/
ELAdrEntry* EL_GetAdrEntry( char* ent_name)
{
ELAdrEntry* CurrentAdrEnt;
CurrentAdrEnt = ELAdrEntStart;
if( CurrentAdrEnt == NULL) {
return NULL;
}
while( strcmp( CurrentAdrEnt->name, ent_name) != 0) {
CurrentAdrEnt = (ELAdrEntry*)CurrentAdrEnt->next;
if( CurrentAdrEnt == NULL) {
break;
}
}
return CurrentAdrEnt;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void* EL_GetGlobalAdr( char* ent_name)
{
u32 adr;
ELAdrEntry* CurrentAdrEnt;
CurrentAdrEnt = EL_GetAdrEntry( 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* EL_FreeAdrTbl( void)
{
ELAdrEntry* FwdAdrEnt;
ELAdrEntry* CurrentAdrEnt;
/*--- ELAdrEntryのリストを解放する ---*/
CurrentAdrEnt = ELAdrEntStart;
if( CurrentAdrEnt) {
while( CurrentAdrEnt->next != NULL) {
FwdAdrEnt = CurrentAdrEnt;
CurrentAdrEnt = CurrentAdrEnt->next;
free( FwdAdrEnt->name); //シンボル名文字列
free( FwdAdrEnt); //構造体自身
}
ELAdrEntStart = NULL;
}
/*------------------------------------*/
}
#endif
/*------------------------------------------------------
ELFオブジェクトからデータを読み出すスタブ
-----------------------------------------------------*/
void ELi_ReadFile( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
{
fseek( file_struct, file_offset, SEEK_SET);
fread( buf, 1, size, file_struct);
/* FS_SeekFile( file_struct, (s32)(file_offset), FS_SEEK_SET);
FS_ReadFile( file_struct, buf, (s32)(size));*/
}
void ELi_ReadMem( void* buf, void* file_struct, u32 file_base, u32 file_offset, u32 size)
{
/* MI_CpuCopy8( (void*)(file_base + file_offset),
buf,
size);*/
memcpy( buf,
(void*)(file_base + file_offset),
size);
}

192
tools/makelst/elf_loader.h Normal file
View File

@ -0,0 +1,192 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: elf_loader.h
Copyright 2006 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 "types.h"
#include "elf.h"
#include "stdio.h"
/*------------------------------------------------------
()
-----------------------------------------------------*/
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;
/*------------------------------------------------------
ELFオブジェクトの管理
-----------------------------------------------------*/
typedef void (*ELi_ReadFunc)( 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リストの先頭 */
ELi_ReadFunc ELi_ReadStub; /* リードスタブ関数 */
void* FileStruct; /* ファイル構造体 */
u32 mem_adr; /*最初にロードされたセクションのsh_addrが入る(DSのROMヘッダ用パラメータ)*/
}ELHandle;
/*------------------------------------------------------
-----------------------------------------------------*/
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; /*解決したときにセットする(消しても良いことを識別する)フラグ*/
ELAdrEntry* AdrEnt; /*アドレステーブルから探し出したエントリの場所*/
}ELUnresolvedEntry;
/* ELHandle の process値 */
#define EL_FAILED 0x00
#define EL_INITIALIZED 0x5A
#define EL_COPIED 0xF0
#define EL_RELOCATED 0xF1
/*---------------------------------------------------------
ELFオブジェクトのサイズを求める
--------------------------------------------------------*/
u32 EL_GetElfSize( const void* buf);
/*------------------------------------------------------
-----------------------------------------------------*/
void EL_Init( void);
/*------------------------------------------------------
ELHandle構造体を初期化する
-----------------------------------------------------*/
BOOL EL_InitHandle( ELHandle* ElfHandle);
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをファイルからバッファに再配置する
-----------------------------------------------------*/
u16 EL_LoadLibraryfromFile( ELHandle* ElfHandle, FILE* ObjFile, void* buf);
/*------------------------------------------------------
ELFオブジェクトまたはそのアーカイブをメモリからバッファに再配置する
-----------------------------------------------------*/
u16 EL_LoadLibraryfromMem( ELHandle* ElfHandle, void* obj_image, u32 obj_len, void* buf);
/*------------------------------------------------------
使
-----------------------------------------------------*/
u16 EL_ResolveAllLibrary( void);
/*------------------------------------------------------
-----------------------------------------------------*/
u16 EL_ExtractStaticSym1( void);
/*------------------------------------------------------
APIとして書き出す
-----------------------------------------------------*/
u16 EL_ExtractStaticSym2( void);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL EL_RemoveAdrEntry( ELAdrEntry* AdrEnt);
/*------------------------------------------------------
-----------------------------------------------------*/
void EL_AddAdrEntry( ELAdrEntry* AdrEnt);
/*------------------------------------------------------
-----------------------------------------------------*/
ELAdrEntry* EL_GetAdrEntry( char* ent_name);
/*------------------------------------------------------
-----------------------------------------------------*/
void* EL_GetGlobalAdr( char* ent_name);
/*他に必要そうな関数*/
//ロードに必要なメモリのバイト数を算出する関数
//EL_FreeLibrary
#endif /*_ELF_LOADER_H_*/

View File

@ -0,0 +1,819 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: loader_subset.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 <stdlib.h>
#include <string.h>
#include "loader_subset.h"
extern ELUnresolvedEntry* ELUnrEntStart;
extern u16 dbg_print_flag;
extern u32 unresolved_table_block_flag;
//ARM7かどうかを判別するときは、
//#ifdef SDK_ARM7
//#endif /*SDK_ARM7*/
/*------------------------------------------------------
-----------------------------------------------------*/
#define ALIGN( addr, align_size ) (((addr) & ~((align_size) - 1)) + (align_size))
static u32 ELi_ALIGN( u32 addr, u32 align_size);
u32 ELi_ALIGN( u32 addr, u32 align_size)
{
u32 aligned_addr;
if( (addr % align_size) == 0) {
aligned_addr = addr;
}else{
aligned_addr = (((addr) & ~((align_size) - 1)) + (align_size));
}
return aligned_addr;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopySectionToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr)
{
u32 load_start;
Elf32_Addr sh_size;
/*アラインメントをとる*/
// load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), (Shdr->sh_addralign));
load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
/*サイズ設定*/
sh_size = Shdr->sh_size;
/*コピー*/
ElfHandle->ELi_ReadStub( (void*)load_start,
ElfHandle->FileStruct,
(u32)(ElfHandle->ar_head),
(u32)(ElfHandle->elf_offset)+(u32)(Shdr->sh_offset),
sh_size);
/*バッファポインタを移動*/
ElfHandle->buf_current = (void*)(load_start + sh_size);
/*ロードした先頭アドレスを返す*/
return (void*)load_start;
}
/*------------------------------------------------------
0
-----------------------------------------------------*/
void* ELi_AllocSectionToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr)
{
u32 load_start;
Elf32_Addr sh_size;
/*アラインメントをとる*/
// load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), (Shdr->sh_addralign));
load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
/*サイズ設定*/
sh_size = Shdr->sh_size;
/*バッファポインタを移動*/
ElfHandle->buf_current = (void*)(load_start + sh_size);
/*0で埋める.bssセクションを想定しているため*/
memset( (void*)load_start, 0, sh_size);
/*確保した先頭アドレスを返す*/
return (void*)load_start;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_GetShdr( ELHandle* ElfHandle, u32 index, Elf32_Shdr* Shdr)
{
u32 offset;
offset = (ElfHandle->CurrentEhdr.e_shoff) + ((u32)(ElfHandle->shentsize) * index);
ElfHandle->ELi_ReadStub( Shdr,
ElfHandle->FileStruct,
(u32)(ElfHandle->ar_head),
(u32)(ElfHandle->elf_offset) + offset,
sizeof( Elf32_Shdr));
}
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_GetSent( ELHandle* ElfHandle, u32 index, void* entry_buf, u32 offset, u32 size)
{
Elf32_Shdr Shdr;
//u32 entry_adr;
ELi_GetShdr( ElfHandle, index, &Shdr);
ElfHandle->ELi_ReadStub( entry_buf,
ElfHandle->FileStruct,
(u32)(ElfHandle->ar_head),
(u32)(ElfHandle->elf_offset) + (u32)(Shdr.sh_offset) + offset,
size);
}
/*------------------------------------------------------
Rel,Rela,Symなどエントリサイズが固定のセクションのみ
Shdr :
index : (0)
-----------------------------------------------------*/
void ELi_GetEntry( ELHandle* ElfHandle, Elf32_Shdr* Shdr, u32 index, void* entry_buf)
{
u32 offset;
offset = (u32)(Shdr->sh_offset) + ((Shdr->sh_entsize) * index);
ElfHandle->ELi_ReadStub( entry_buf,
ElfHandle->FileStruct,
(u32)(ElfHandle->ar_head),
(u32)(ElfHandle->elf_offset) + offset,
Shdr->sh_entsize);
}
/*------------------------------------------------------
STRセクションヘッダの指定インデックスの文字列を取得する
Shdr :
index : (0)
-----------------------------------------------------*/
void ELi_GetStrAdr( ELHandle* ElfHandle, u32 strsh_index, u32 ent_index, char* str, u32 len)
{
/*文字列エントリの先頭アドレス*/
ELi_GetSent( ElfHandle, strsh_index, str, ent_index, len);
}
/*------------------------------------------------------
<Relセクションヘッダ>
RelShdr->sh_link :
RelShdr->sh_info : (rel.textの.textを表す)
<Relエントリ>
Rel->r_offset :
ELF32_R_SYM( Rel->r_info) :
ELF32_R_TYPE( Rel->r_info) :
<Symセクションヘッダ>
SymShdr->sh_link :
<Symエントリ>
Sym->st_name :
Sym->st_value :
Sym->st_size :
Sym->st_shndx :
ELF32_ST_BIND( Sym->st_info) : (LOCAL or GLOBAL)
ELF32_ST_TYPE( Sym->st_info) : ()
-----------------------------------------------------*/
void ELi_RelocateSym( ELHandle* ElfHandle, u32 relsh_index)
{
u32 i;
u32 num_of_sym; //シンボルの全体数
u32 num_of_rel; //再定義すべきシンボルの数
Elf32_Shdr RelOrRelaShdr; //RELまたはRELAセクションヘッダ
Elf32_Rela CurrentRela; //RELまたはRELAエントリのコピー先
Elf32_Shdr* SymShdr;
ELSymEx* CurrentSymEx;
ELSymEx* FwdSymEx;
ELSymEx DmySymEx;
ELShdrEx* TargetShdrEx;
ELShdrEx* CurrentShdrEx;
u32 relocation_adr;
char sym_str[128];
u32 copy_size;
ELAdrEntry* CurrentAdrEntry;
u32 sym_loaded_adr;
ELAdrEntry* ExportAdrEntry;
u32 thumb_func_flag;
ELUnresolvedEntry UnresolvedInfo;
ELUnresolvedEntry* UnrEnt;
u32 unresolved_num = 0;
/*REL or RELAセクションヘッダ取得*/
ELi_GetShdr( ElfHandle, relsh_index, &RelOrRelaShdr);
/*RELセクションとSYMセクションは1対1対応*/
ELi_GetShdr( ElfHandle, RelOrRelaShdr.sh_link, &(ElfHandle->SymShdr));
SymShdr = &(ElfHandle->SymShdr);
if( dbg_print_flag == 1) {
printf( "SymShdr->link:%02x, SymShdr->info:%02x\n",
(int)(SymShdr->sh_link), (int)(SymShdr->sh_info));
}
/*ターゲットセクションのEXヘッダ*/
TargetShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, RelOrRelaShdr.sh_info);
num_of_rel = (RelOrRelaShdr.sh_size) / (RelOrRelaShdr.sh_entsize); //再定義すべきシンボルの数
num_of_sym = (SymShdr->sh_size) / (SymShdr->sh_entsize); //シンボルの全体数
/*---------- ELSymExのリストを作る ----------*/
CurrentSymEx = &DmySymEx;
for( i=0; i<num_of_sym; i++) {
CurrentSymEx->next = (void*)(malloc( sizeof(ELSymEx)));
CurrentSymEx = (ELSymEx*)(CurrentSymEx->next);
/*シンボルエントリをコピー*/
ELi_GetEntry( ElfHandle, SymShdr, i, &(CurrentSymEx->Sym));
/*デバッグ情報フラグをセット*/
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, CurrentSymEx->Sym.st_shndx);
if( CurrentShdrEx) {
CurrentSymEx->debug_flag = CurrentShdrEx->debug_flag;
}else{
CurrentSymEx->debug_flag = 0;
}
// printf( "sym_no: %02x ... st_shndx: %04x\n", i, CurrentSymEx->Sym.st_shndx);
}
CurrentSymEx->next = NULL;
ElfHandle->SymEx = DmySymEx.next;
/*-------------------------------------------*/
/*----- ELSymExのThumbフラグをセット関数シンボルだけ必要-----*/
CurrentSymEx = ElfHandle->SymEx;
for( i=0; i<num_of_sym; i++) {
if( ELF32_ST_TYPE( CurrentSymEx->Sym.st_info) == STT_FUNC) {
CurrentSymEx->thumb_flag = (u16)(ELi_CodeIsThumb( ElfHandle, CurrentSymEx->Sym.st_shndx,
CurrentSymEx->Sym.st_value));
}else{
CurrentSymEx->thumb_flag = 0;
}
CurrentSymEx = CurrentSymEx->next;
}
/*---------------------------------------------------------------*/
/*--- 再定義が必要なシンボルの再定義 ---*/
for( i=0; i<num_of_rel; i++) {
/*- RelまたはRelaエントリ取得 -*/
ELi_GetEntry( ElfHandle, &RelOrRelaShdr, i, &CurrentRela);
if( RelOrRelaShdr.sh_type == SHT_REL) {
CurrentRela.r_addend = 0;
}
/*-----------------------------*/
/*シンボルExエントリ取得*/
CurrentSymEx = ELi_GetSymExfromList( ElfHandle->SymEx,
ELF32_R_SYM( CurrentRela.r_info));
if( CurrentSymEx->debug_flag == 1) { /*デバッグ情報の場合*/
}else{ /*デバッグ情報でない場合*/
/**/
ELi_UnresolvedInfoInit( &UnresolvedInfo);
/*書き換えるアドレス仕様書でいう「P」*/
relocation_adr = (TargetShdrEx->loaded_adr) + (CurrentRela.r_offset);
UnresolvedInfo.r_type = ELF32_R_TYPE( CurrentRela.r_info);
UnresolvedInfo.A_ = (CurrentRela.r_addend);
UnresolvedInfo.P_ = (relocation_adr);
UnresolvedInfo.sh_type = (RelOrRelaShdr.sh_type);
/*シンボルのアドレスを突き止める*/
if( CurrentSymEx->Sym.st_shndx == SHN_UNDEF) {
/*アドレステーブルから検索*/
ELi_GetStrAdr( ElfHandle, SymShdr->sh_link, CurrentSymEx->Sym.st_name, sym_str, 128);
CurrentAdrEntry = EL_GetAdrEntry( sym_str);
if( CurrentAdrEntry) {
sym_loaded_adr = (u32)(CurrentAdrEntry->adr);
/*THUMB関数フラグ仕様書でいう「T」THUMB or ARM の判別*/
thumb_func_flag = CurrentAdrEntry->thumb_flag;
if( dbg_print_flag == 1) {
printf( "\n symbol found %s : %8x\n", sym_str, (int)(sym_loaded_adr));
}
}else{
/*見つからなかった時はエラー(S_とT_が解決できない)*/
copy_size = (u32)strlen( sym_str) + 1;
UnresolvedInfo.sym_str = (char*)(malloc( copy_size));
//MI_CpuCopy8( sym_str, UnresolvedInfo.sym_str, copy_size);
memcpy( UnresolvedInfo.sym_str, sym_str, copy_size);
/*グローバルな未解決テーブルに追加*/
copy_size = sizeof( ELUnresolvedEntry);
UnrEnt = (ELUnresolvedEntry*)(malloc( copy_size));
//MI_CpuCopy8( &UnresolvedInfo, UnrEnt, copy_size);
memcpy( UnrEnt, &UnresolvedInfo, copy_size);
if( unresolved_table_block_flag == 0) { //テーブルへの追加が禁止されていなければ
ELi_AddUnresolvedEntry( UnrEnt);
}
unresolved_num++; /*未解決シンボル数をカウント*/
if( dbg_print_flag == 1) {
printf( "WARNING! cannot find symbol : %s\n", sym_str);
}
}
}else{
/*シンボルの所属するセクションのExヘッダ取得*/
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, CurrentSymEx->Sym.st_shndx);
sym_loaded_adr = CurrentShdrEx->loaded_adr;
sym_loaded_adr += CurrentSymEx->Sym.st_value; //sym_loaded_adrは仕様書でいう「S」
/*THUMB関数フラグ仕様書でいう「T」THUMB or ARM の判別*/
thumb_func_flag = CurrentSymEx->thumb_flag;
}
if( !UnresolvedInfo.sym_str) { /*sym_strがセットされているときはシンボル解決不可能*/
/*仕様書と同じ変数名にする*/
UnresolvedInfo.S_ = (sym_loaded_adr);
UnresolvedInfo.T_ = (thumb_func_flag);
/*--------------- シンボルの解決(再配置の実行) ---------------*/
// CurrentSymEx->relocation_val = ELi_DoRelocate( &UnresolvedInfo);
/*------------------------------------------------------------*/
}
}
}
/*-----------------------------------*/
/*--- ライブラリ内のGLOBALシンボルをアドレステーブルに公開する ---*/
for( i=0; i<num_of_sym; i++) {
CurrentSymEx = ELi_GetSymExfromList( ElfHandle->SymEx, i);
/*GLOBALで、かつ関連するセクションがライブラリ内に存在する場合*/
if( ((ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_GLOBAL) ||
(ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_WEAK) ||
(ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_MW_SPECIFIC))&&
(CurrentSymEx->Sym.st_shndx != SHN_UNDEF)) {
ExportAdrEntry = (ELAdrEntry*)(malloc( sizeof(ELAdrEntry))); /*メモリ確保*/
ExportAdrEntry->next = NULL;
ELi_GetStrAdr( ElfHandle, SymShdr->sh_link, CurrentSymEx->Sym.st_name, sym_str, 128);
copy_size = (u32)strlen( sym_str) + 1;
ExportAdrEntry->name = (char*)(malloc( copy_size));
//MI_CpuCopy8( sym_str, ExportAdrEntry->name, copy_size);
memcpy( ExportAdrEntry->name, sym_str, copy_size);
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, CurrentSymEx->Sym.st_shndx);
//Sym.st_valueは偶数/奇数でARM/Thumbを判別できるように調整されている場合があるので、その調整を削除して正味の値を出す
ExportAdrEntry->adr = (void*)(CurrentShdrEx->loaded_adr + ((CurrentSymEx->Sym.st_value)&0xFFFFFFFE));
ExportAdrEntry->func_flag = (u16)(ELF32_ST_TYPE( CurrentSymEx->Sym.st_info));
ExportAdrEntry->thumb_flag = CurrentSymEx->thumb_flag;
if( EL_GetAdrEntry( ExportAdrEntry->name) == NULL) { //入ってなかったら
if( dbg_print_flag == 1) {
printf( "Add Entry : %s(0x%x), func=%d, thumb=%d\n",
ExportAdrEntry->name,
(int)(ExportAdrEntry->adr),
ExportAdrEntry->func_flag,
ExportAdrEntry->thumb_flag);
}
EL_AddAdrEntry( ExportAdrEntry); //登録
}
}
}
/*----------------------------------------------------------------*/
/*------- ELSymExのリストを解放する -------*/
CurrentSymEx = ElfHandle->SymEx;
if( CurrentSymEx) {
while( CurrentSymEx->next != NULL) {
FwdSymEx = CurrentSymEx;
CurrentSymEx = CurrentSymEx->next;
free( FwdSymEx);
}
ElfHandle->SymEx = NULL;
}
/*-----------------------------------------*/
/* 再配置完了後 */
if( unresolved_num == 0) {
ElfHandle->process = EL_RELOCATED;
}
}
/*------------------------------------------------------
makelst専用関数
GLOBALなものを
-----------------------------------------------------*/
void ELi_DiscriminateGlobalSym( ELHandle* ElfHandle, u32 symsh_index)
{
u32 i;
u32 num_of_sym;
Elf32_Shdr CurrentSymShdr;
Elf32_Shdr* SymShdr; //SYMセクションヘッダ
ELSymEx* CurrentSymEx;
ELSymEx* FwdSymEx;
ELSymEx DmySymEx;
ELShdrEx* CurrentShdrEx;
ELAdrEntry* ExportAdrEntry;
char sym_str[128];
u32 copy_size;
/*SYMセクションヘッダ取得*/
ELi_GetShdr( ElfHandle, symsh_index, &CurrentSymShdr);
SymShdr = &CurrentSymShdr;
num_of_sym = (SymShdr->sh_size) / (SymShdr->sh_entsize); //シンボルの全体数
/*---------- ELSymExのリストを作る ----------*/
CurrentSymEx = &DmySymEx;
for( i=0; i<num_of_sym; i++) {
CurrentSymEx->next = (void*)(malloc( sizeof(ELSymEx)));
CurrentSymEx = (ELSymEx*)(CurrentSymEx->next);
/*シンボルエントリをコピー*/
ELi_GetEntry( ElfHandle, SymShdr, i, &(CurrentSymEx->Sym));
/*デバッグ情報フラグをセット*/
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, CurrentSymEx->Sym.st_shndx);
if( CurrentShdrEx) {
CurrentSymEx->debug_flag = CurrentShdrEx->debug_flag;
}else{
CurrentSymEx->debug_flag = 0;
}
// printf( "sym_no: %02x ... st_shndx: %04x\n", i, CurrentSymEx->Sym.st_shndx);
}
CurrentSymEx->next = NULL;
ElfHandle->SymEx = DmySymEx.next;
/*-------------------------------------------*/
/*----- ELSymExのThumbフラグをセット関数シンボルだけ必要-----*/
CurrentSymEx = ElfHandle->SymEx;
for( i=0; i<num_of_sym; i++) {
if( ELF32_ST_TYPE( CurrentSymEx->Sym.st_info) == STT_FUNC) {
CurrentSymEx->thumb_flag = (u16)(ELi_CodeIsThumb( ElfHandle, CurrentSymEx->Sym.st_shndx,
CurrentSymEx->Sym.st_value));
}else{
CurrentSymEx->thumb_flag = 0;
}
CurrentSymEx = CurrentSymEx->next;
}
/*---------------------------------------------------------------*/
/*--- ライブラリ内のGLOBALシンボルをアドレステーブルに公開する ---*/
for( i=0; i<num_of_sym; i++) {
CurrentSymEx = ELi_GetSymExfromList( ElfHandle->SymEx, i);
/*GLOBALで、かつ関連するセクションがライブラリ内に存在する場合*/
if( ((ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_GLOBAL) ||
(ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_WEAK) ||
(ELF32_ST_BIND( CurrentSymEx->Sym.st_info) == STB_MW_SPECIFIC))&&
(CurrentSymEx->Sym.st_shndx != SHN_UNDEF)) {
ExportAdrEntry = (ELAdrEntry*)(malloc( sizeof(ELAdrEntry))); /*メモリ確保*/
ExportAdrEntry->next = NULL;
ELi_GetStrAdr( ElfHandle, SymShdr->sh_link, CurrentSymEx->Sym.st_name, sym_str, 128);
copy_size = (u32)strlen( sym_str) + 1;
ExportAdrEntry->name = (char*)(malloc( copy_size));
//MI_CpuCopy8( sym_str, ExportAdrEntry->name, copy_size);
memcpy( ExportAdrEntry->name, sym_str, copy_size);
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, CurrentSymEx->Sym.st_shndx);
//Sym.st_valueは偶数/奇数でARM/Thumbを判別できるように調整されている場合があるので、その調整を削除して正味の値を出す
ExportAdrEntry->adr = (void*)(CurrentShdrEx->loaded_adr + ((CurrentSymEx->Sym.st_value)&0xFFFFFFFE));
ExportAdrEntry->func_flag = (u16)(ELF32_ST_TYPE( CurrentSymEx->Sym.st_info));
ExportAdrEntry->thumb_flag = CurrentSymEx->thumb_flag;
if( EL_GetAdrEntry( ExportAdrEntry->name) == NULL) { //入ってなかったら
if( dbg_print_flag == 1) {
printf( "Add Entry : %s(0x%x), func=%d, thumb=%d\n",
ExportAdrEntry->name,
(int)(ExportAdrEntry->adr),
ExportAdrEntry->func_flag,
ExportAdrEntry->thumb_flag);
}
EL_AddAdrEntry( ExportAdrEntry); //登録
}
}
}
/*----------------------------------------------------------------*/
/*------- ELSymExのリストを解放する -------*/
CurrentSymEx = ElfHandle->SymEx;
if( CurrentSymEx) {
while( CurrentSymEx->next != NULL) {
FwdSymEx = CurrentSymEx;
CurrentSymEx = CurrentSymEx->next;
free( FwdSymEx);
}
ElfHandle->SymEx = NULL;
}
/*-----------------------------------------*/
}
/*------------------------------------------------------
r_type,S_,A_,P_,T_が全て分かっている必要がある
-----------------------------------------------------*/
#define _S_ (UnresolvedInfo->S_)
#define _A_ (UnresolvedInfo->A_)
#define _P_ (UnresolvedInfo->P_)
#define _T_ (UnresolvedInfo->T_)
u32 ELi_DoRelocate( ELUnresolvedEntry* UnresolvedInfo)
{
s32 signed_val;
u32 relocation_val = 0;
u32 relocation_adr;
relocation_adr = _P_;
switch( (UnresolvedInfo->r_type)) {
case R_ARM_PC24:
case R_ARM_PLT32:
case R_ARM_CALL:
case R_ARM_JUMP24:
if( UnresolvedInfo->sh_type == SHT_REL) {
_A_ = (((*(vu32*)relocation_adr)|0xFF800000) << 2); //一般的には-8になっているはず
}
signed_val = (( (s32)(_S_) + _A_) | (s32)(_T_)) - (s32)(_P_);
if( _T_) { /*BLX命令でARMからThumbに飛ぶ(v5未満だとBL→ベニアでBXという仕組みが必要)*/
relocation_val = (0xFA000000) | ((signed_val>>2) & 0x00FFFFFF) | (((signed_val>>1) & 0x1)<<24);
}else{ /*BL命令でARMからARMに飛ぶ*/
signed_val >>= 2;
relocation_val = (*(vu32*)relocation_adr & 0xFF000000) | (signed_val & 0x00FFFFFF);
}
*(vu32*)relocation_adr = relocation_val;
break;
case R_ARM_ABS32:
relocation_val = (( _S_ + _A_) | _T_);
*(vu32*)relocation_adr = relocation_val;
break;
case R_ARM_REL32:
relocation_val = (( _S_ + _A_) | _T_) - _P_;
*(vu32*)relocation_adr = relocation_val;
break;
case R_ARM_LDR_PC_G0:
signed_val = ( (s32)(_S_) + _A_) - (s32)(_P_);
signed_val >>= 2;
relocation_val = (*(vu32*)relocation_adr & 0xFF000000) | (signed_val & 0x00FFFFFF);
*(vu32*)relocation_adr = relocation_val;
break;
case R_ARM_ABS16:
case R_ARM_ABS12:
case R_ARM_THM_ABS5:
case R_ARM_ABS8:
relocation_val = _S_ + _A_;
*(vu32*)relocation_adr = relocation_val;
break;
case R_ARM_THM_PC22:/*別名R_ARM_THM_CALL*/
if( UnresolvedInfo->sh_type == SHT_REL) {
_A_ = (((*(vu16*)relocation_adr & 0x07FF)<<11) + ((*((vu16*)(relocation_adr)+1)) & 0x07FF));
_A_ = (_A_ | 0xFFC00000) << 1; //一般的には-4になっているはず(PCは現命令アドレス+4なので)
}
signed_val = (( (s32)(_S_) + _A_) | (s32)(_T_)) - (s32)(_P_);
signed_val >>= 1;
if( _T_) { /*BL命令でThumbからThumbに飛ぶ*/
relocation_val = (*(vu16*)relocation_adr & 0xF800) | ((signed_val>>11) & 0x07FF) +
((((*((vu16*)(relocation_adr)+1)) & 0xF800) | (signed_val & 0x07FF)) << 16);
}else{ /*BLX命令でThumbからARMに飛ぶ(v5未満だとBL→ベニアでBXという仕組みが必要)*/
if( (signed_val & 0x1)) { //_P_が4バイトアラインされていないとここに来る
signed_val += 1;
}
relocation_val = (*(vu16*)relocation_adr & 0xF800) | ((signed_val>>11) & 0x07FF) +
((((*((vu16*)(relocation_adr)+1)) & 0xE800) | (signed_val & 0x07FF)) << 16);
}
*(vu16*)relocation_adr = (vu16)relocation_val;
*((vu16*)relocation_adr+1) = (vu16)((u32)(relocation_val) >> 16);
break;
case R_ARM_THM_JUMP24:
break;
default:
if( dbg_print_flag == 1) {
printf( "ERROR! : unsupported relocation type!\n");
}
break;
}
return relocation_val;
}
#undef _S_
#undef _A_
#undef _P_
#undef _T_
/*------------------------------------------------------
ELSymExを取り出す
-----------------------------------------------------*/
ELSymEx* ELi_GetSymExfromList( ELSymEx* SymExStart, u32 index)
{
u32 i;
ELSymEx* SymEx;
SymEx = SymExStart;
for( i=0; i<index; i++) {
SymEx = (ELSymEx*)(SymEx->next);
if( SymEx == NULL) {
break;
}
}
return SymEx;
}
/*------------------------------------------------------
ELShdrExを取り出す
-----------------------------------------------------*/
ELShdrEx* ELi_GetShdrExfromList( ELShdrEx* ShdrExStart, u32 index)
{
u32 i;
ELShdrEx* ShdrEx;
ShdrEx = ShdrExStart;
for( i=0; i<index; i++) {
ShdrEx = (ELShdrEx*)(ShdrEx->next);
if( ShdrEx == NULL) {
break;
}
}
return ShdrEx;
}
/*------------------------------------------------------
".debug"
.rel.debug sh_info
 
-----------------------------------------------------*/
BOOL ELi_ShdrIsDebug( ELHandle* ElfHandle, u32 index)
{
Elf32_Shdr TmpShdr;
char shstr[6];
/*-- セクション名の文字列を6文字取得 --*/
ELi_GetShdr( ElfHandle, index, &TmpShdr);
ELi_GetStrAdr( ElfHandle, ElfHandle->CurrentEhdr.e_shstrndx,
TmpShdr.sh_name, shstr, 6);
/*-------------------------------------*/
if( strncmp( shstr, ".debug", 6) == 0) { /*デバッグセクションの場合*/
return TRUE;
}else{ /*デバッグセクションに関する再配置セクションの場合*/
if( (TmpShdr.sh_type == SHT_REL) || (TmpShdr.sh_type == SHT_RELA)) {
if( ELi_ShdrIsDebug( ElfHandle, TmpShdr.sh_info) == TRUE) {
return TRUE;
}
}
}
return FALSE;
}
/*------------------------------------------------------
ElfHandleのSymExテーブルを調べ
 ARMかTHUMBかを判定する
ElfHandle->SymShdr ElfHandle->SymEx
sh_index : 調
offset : 調
-----------------------------------------------------*/
u32 ELi_CodeIsThumb( ELHandle* ElfHandle, u16 sh_index, u32 offset)
{
u32 i;
u32 thumb_flag;
Elf32_Shdr* SymShdr;
char str_adr[3];
ELSymEx* CurrentSymEx;
/*シンボルのセクションヘッダとSymExリスト取得*/
SymShdr = &(ElfHandle->SymShdr);
CurrentSymEx = ElfHandle->SymEx;
i = 0;
thumb_flag = 0;
while( CurrentSymEx != NULL) {
if( CurrentSymEx->Sym.st_shndx == sh_index) {
ELi_GetStrAdr( ElfHandle, SymShdr->sh_link, CurrentSymEx->Sym.st_name, str_adr, 3);
if( strncmp( str_adr, "$a\0", strlen("$a\0")) == 0) {
thumb_flag = 0;
}else if( strncmp( str_adr, "$t\0", strlen("$t\0")) == 0) {
thumb_flag = 1;
}
if( CurrentSymEx->Sym.st_value > offset) {
break;
}
}
CurrentSymEx = CurrentSymEx->next;
i++;
}
return thumb_flag;
}
/*---------------------------------------------------------
--------------------------------------------------------*/
void ELi_UnresolvedInfoInit( ELUnresolvedEntry* UnresolvedInfo)
{
UnresolvedInfo->sym_str = NULL;
UnresolvedInfo->r_type = 0;
UnresolvedInfo->S_ = 0;
UnresolvedInfo->A_ = 0;
UnresolvedInfo->P_ = 0;
UnresolvedInfo->T_ = 0;
UnresolvedInfo->remove_flag = 0;
}
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL ELi_RemoveUnresolvedEntry( ELUnresolvedEntry* UnrEnt)
{
ELUnresolvedEntry DmyUnrEnt;
ELUnresolvedEntry* CurrentUnrEnt;
if( UnrEnt == NULL) {
return FALSE;
}
DmyUnrEnt.next = ELUnrEntStart;
CurrentUnrEnt = &DmyUnrEnt;
while( CurrentUnrEnt->next != UnrEnt) {
if( CurrentUnrEnt->next == NULL) {
return FALSE;
}else{
CurrentUnrEnt = (ELUnresolvedEntry*)(CurrentUnrEnt->next);
}
}
CurrentUnrEnt->next = UnrEnt->next;
free( UnrEnt->sym_str);
free( UnrEnt);
ELUnrEntStart = DmyUnrEnt.next;
return TRUE;
}
/*---------------------------------------------------------
--------------------------------------------------------*/
void ELi_AddUnresolvedEntry( ELUnresolvedEntry* UnrEnt)
{
ELUnresolvedEntry DmyUnrEnt;
ELUnresolvedEntry* CurrentUnrEnt;
if( !ELUnrEntStart) {
ELUnrEntStart = UnrEnt;
}else{
DmyUnrEnt.next = ELUnrEntStart;
CurrentUnrEnt = &DmyUnrEnt;
while( CurrentUnrEnt->next != NULL) {
CurrentUnrEnt = CurrentUnrEnt->next;
}
CurrentUnrEnt->next = (void*)UnrEnt;
}
UnrEnt->next = NULL;
}
/*------------------------------------------------------
-----------------------------------------------------*/
ELUnresolvedEntry* ELi_GetUnresolvedEntry( char* ent_name)
{
ELUnresolvedEntry* CurrentUnrEnt;
CurrentUnrEnt = ELUnrEntStart;
if( CurrentUnrEnt == NULL) {
return NULL;
}
while( 1) {
if( (strcmp( CurrentUnrEnt->sym_str, ent_name) == 0)&&
(CurrentUnrEnt->remove_flag == 0)) {
break;
}
CurrentUnrEnt = (ELUnresolvedEntry*)CurrentUnrEnt->next;
if( CurrentUnrEnt == NULL) {
break;
}
}
return CurrentUnrEnt;
}

View File

@ -0,0 +1,128 @@
/*---------------------------------------------------------------------------*
Project: CTR - ELF Loader
File: loader_subset.h
Copyright 2006 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 "types.h"
#include "elf.h"
#include "elf_loader.h"
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopySectionToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_AllocSectionToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_GetShdr( ELHandle* ElfHandle, u32 index, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_GetSent( ELHandle* ElfHandle, u32 index, void* entry_buf, u32 offset, u32 size);
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_GetEntry( ELHandle* ElfHandle, Elf32_Shdr* Shdr, u32 index, void* entry_buf);
/*------------------------------------------------------
STRセクションヘッダの指定インデックスの文字列を取得する
-----------------------------------------------------*/
void ELi_GetStrAdr( ELHandle* ElfHandle, u32 strsh_index, u32 ent_index, char* str, u32 len);
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_RelocateSym( ELHandle* ElfHandle, u32 relsh_index);
/*------------------------------------------------------
makelst専用関数
GLOBALなものを
-----------------------------------------------------*/
void ELi_DiscriminateGlobalSym( ELHandle* ElfHandle, u32 symsh_index);
/*------------------------------------------------------
-----------------------------------------------------*/
u32 ELi_DoRelocate( ELUnresolvedEntry* UnresolvedInfo);
/*------------------------------------------------------
ELSymExを取り出す
-----------------------------------------------------*/
ELSymEx* ELi_GetSymExfromList( ELSymEx* SymExStart, u32 index);
/*------------------------------------------------------
ELShdrExを取り出す
-----------------------------------------------------*/
ELShdrEx* ELi_GetShdrExfromList( ELShdrEx* ShdrExStart, u32 index);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL ELi_ShdrIsDebug( ELHandle* ElfHandle, u32 index);
/*------------------------------------------------------
ElfHandleのSymExテーブルを調べ
 ARMかTHUMBかを判定する
-----------------------------------------------------*/
u32 ELi_CodeIsThumb( ELHandle* ElfHandle, u16 sh_index, u32 offset);
/*---------------------------------------------------------
--------------------------------------------------------*/
void ELi_UnresolvedInfoInit( ELUnresolvedEntry* UnresolvedInfo);
/*------------------------------------------------------
-----------------------------------------------------*/
BOOL ELi_RemoveUnresolvedEntry( ELUnresolvedEntry* UnrEnt);
/*---------------------------------------------------------
--------------------------------------------------------*/
void ELi_AddUnresolvedEntry( ELUnresolvedEntry* UnrEnt);
/*------------------------------------------------------
-----------------------------------------------------*/
ELUnresolvedEntry* ELi_GetUnresolvedEntry( char* ent_name);
#endif /*_LOADER_SUBSET_H_*/

279
tools/makelst/makelst.c Normal file
View File

@ -0,0 +1,279 @@
/*---------------------------------------------------------------------------*
Project: tools - makedsrom
File: makesdrom.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.
$NoKeywords: $
*---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h> // atoi()
#include <string.h>
#include <ctype.h>
#include <getopt.h> // getopt()
#include "version.h"
#include "types.h"
#include "elf.h"
#include "elf_loader.h"
#include "searcharg.h"
#define DS_ROM_HEADER_SIZE 0x4000
char c_source_line_str[256];
#define C_SOURCE_FILENAME "staticsymlist.c"
FILE* CSourceFilep;
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
u32 adr_ALIGN( u32 addr, u32 align_size);
void file_write( char* c_str, FILE* Fp);
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
u16 dbg_print_flag;
u16 unresolved_table_block_flag = 0;
/*---------------------------------------------------------------------------*
* MAIN
*---------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{
int i;
FILE *FHp;
u32 binbuf[4];
ELHandle ElfH;
char* c_filename;
SAArgInfo ArgInfo;
u16 result;
// printf( "binbuf : %x\n", binbuf);
/*
for( i=0; i<argc; i++) {
fprintf(stdout, "%s\n", argv[i]);
}
*/
/*-----------------------------------------------------*/
dbg_print_flag = 0;
SA_searchopt( &ArgInfo, argc, argv);
// SA_printf( &ArgInfo);
/*オプションが少ないとき*/
if( argc == 1) {
printf( "Development Tool - makelst - Make \"C\" source file\n");
printf( "Build %s\n\n", __DATE__);
printf( "Usage: makelst [-o output-file] [-static static-files ...] [-dll dll-files ...]\n\n");
exit( 1);
}
/*-d オプションがあればデバッグ表示フラグをセット*/
/* for( i=0; i<ArgList.opt_num; i++) {
if( strcmp( ArgList.opt[i], "-d") == 0) {
if( ArgList.opt_arg[i] == NULL) {
dbg_print_flag = 1;
break;
}else{
printf( "Illegal argument \"%s\"\n", ArgList.opt_arg[i]);
exit( 1);
}
}
}*/
/*---------- 不正な入力を警告 ----------*/
{
/*オプションなしの引数チェック*/
SAOptList* CurrentOptList;
CurrentOptList = SA_IsThereOpt( &ArgInfo, "\0");
if( CurrentOptList != NULL) {
printf( "invalid argument (%s)\n", CurrentOptList->NameList->name);
exit( 0);
}
/*不正オプションチェック*/
CurrentOptList = ArgInfo.OptList;
for( i=0; i<(ArgInfo.opt_num); i++) {
if( ( strcmp(CurrentOptList->opt_name, "\0" ) != 0) &&
( strcmp(CurrentOptList->opt_name, "-d\0" ) != 0) &&
( strcmp(CurrentOptList->opt_name, "-o\0" ) != 0) &&
( strcmp(CurrentOptList->opt_name, "-dll\0" ) != 0) &&
( strcmp(CurrentOptList->opt_name, "-static\0") != 0)) {
printf( "invalid option (%s)\n", CurrentOptList->opt_name);
exit( 0);
}
CurrentOptList = CurrentOptList->next;
}
}
/*--------------------------------------*/
EL_Init();
unresolved_table_block_flag = 0; //Unresolvedテーブルへの追加禁止を解除
/*----------- -dllオプション解析 ----------------*/
{
SAOptList* CurrentOptList;
SANameList* CurrentNameList;
CurrentOptList = SA_IsThereOpt( &ArgInfo, "-dll\0");
if( CurrentOptList) {
if( CurrentOptList->name_num == 0) {
printf( "no input dll file(s).\n");
exit( 0);
}
CurrentNameList = CurrentOptList->NameList;
for( i=0; i<(CurrentOptList->name_num); i++) {
FHp = fopen( CurrentNameList->name, "rb");
if( FHp == NULL) {
printf( "cannot open file \"%s\".\n", CurrentNameList->name);
exit( 1);
}
EL_InitHandle( &ElfH);
result = EL_LoadLibraryfromFile( &ElfH, FHp, binbuf);
fclose( FHp);
CurrentNameList = CurrentNameList->next;
}
}else{
printf( "no input dll file(s).\n");
exit( 0);
}
}
/*-----------------------------------------------*/
EL_ResolveAllLibrary();
/*------------- -sオプション解析 --------------*/
unresolved_table_block_flag = 1; //Unresolvedテーブルに追加しないようにする
{
SAOptList* CurrentOptList;
SANameList* CurrentNameList;
CurrentOptList = SA_IsThereOpt( &ArgInfo, "-static\0");
if( CurrentOptList) {
if( CurrentOptList->name_num == 0) {
printf( "no input static file(s).\n");
exit( 0);
}
CurrentNameList = CurrentOptList->NameList;
for( i=0; i<(CurrentOptList->name_num); i++) {
FHp = fopen( CurrentNameList->name, "rb");
if( FHp == NULL) {
printf( "cannot open file \"%s\".\n", CurrentNameList->name);
exit( 1);
}
EL_InitHandle( &ElfH);
result = EL_LoadLibraryfromFile( &ElfH, FHp, binbuf);
fclose( FHp);
CurrentNameList = CurrentNameList->next;
}
}else{
printf( "no input static file(s).\n");
exit( 0);
}
}
/*---------------------------------------------*/
/*仮のCソースファイル名生成*/
c_filename = malloc( strlen( C_SOURCE_FILENAME));
strcpy( c_filename, C_SOURCE_FILENAME);
/*-o オプションがあれば指定ファイル名に変更*/
{
SAOptList* CurrentOptList;
SANameList* CurrentNameList;
CurrentOptList = SA_IsThereOpt( &ArgInfo, "-o\0");
if( CurrentOptList) {
if( CurrentOptList->name_num != 0) {
CurrentNameList = CurrentOptList->NameList;
c_filename = CurrentNameList->name;
}else{
printf( "error : no filename after \"-o\" option.\n\n");
exit( 1);
}
}
}
CSourceFilep = fopen( c_filename, "w");
if( !CSourceFilep) {
printf( "error : cannot create file \"%s\".\n\n", c_filename);
exit( 1);
}
file_write( "/*This file generated automatically by the \"makelst\".*/\n", CSourceFilep);
file_write( "\n", CSourceFilep);
file_write( "#ifndef __STATIC_SYM_LIST__\n", CSourceFilep);
file_write( "#define __STATIC_SYM_LIST__\n", CSourceFilep);
file_write( "\n", CSourceFilep);
file_write( "#include <ctr.h>\n", CSourceFilep);
file_write( "#include <elf_loader.h>\n", CSourceFilep);
file_write( "\n", CSourceFilep);
EL_ResolveAllLibrary(); //抽出シンボルのマーキング
EL_ExtractStaticSym1(); //構造体設定部分
file_write( "\n\n", CSourceFilep);
file_write( "/*--------------------------------\n", CSourceFilep);
file_write( " API\n", CSourceFilep);
file_write( " --------------------------------*/\n", CSourceFilep);
file_write( "void elAddStaticSym( void)\n", CSourceFilep);
file_write( "{\n", CSourceFilep);
EL_ExtractStaticSym2(); //API呼び出し部分
file_write( "}\n", CSourceFilep);
unresolved_table_block_flag = 0; //Unresolvedテーブルへの追加禁止を解除
file_write( "\n", CSourceFilep);
file_write( "#endif /*__STATIC_SYM_LIST__*/\n", CSourceFilep);
fclose( CSourceFilep);
/*---------------------------------------------*/
printf( "\"C\" source file \"%s\" is generated.\n\n", c_filename);
exit( 0);
/*-----------------------------------------------------*/
return 0;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
u32 adr_ALIGN( u32 addr, u32 align_size)
{
u32 aligned_addr;
if( (addr % align_size) == 0) {
aligned_addr = addr;
}else{
aligned_addr = (((addr) & ~((align_size) - 1)) + (align_size));
}
return aligned_addr;
}
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
void file_write( char* c_str, FILE* Fp)
{
fwrite( c_str, 1, strlen( c_str), Fp);
}

7
tools/makelst/readme.txt Normal file
View File

@ -0,0 +1,7 @@
・makelst
DLL側とstatic側のelfファイルを入力すると、
static側シンボルをDLLローダーに渡すAPIをCソースとして生成します。
このCソースファイルはstatic側に含めてリンクしてください。

190
tools/makelst/searcharg.c Normal file
View File

@ -0,0 +1,190 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "searcharg.h"
/*
char* opt[7];
char* opt_arg[7];
char* arg[7];
int opt_num;
int arg_num;
*/
char opt_name_null[1] = { '\0'};
static void SA_insertOpt( SAArgInfo* ArgInfo, char* opt_name);
static void SA_insertName( SAArgInfo* ArgInfo, char* name);
/*引数を解析する*/
void SA_searchopt( SAArgInfo* ArgInfo, int argc, char* argv[])
{
int i;
/* 0で初期化 */
memset( ArgInfo, 0, sizeof( SAArgInfo));
for( i=1; i<argc; i++) {
if( strncmp( argv[i], "-", 1) == 0) {
SA_insertOpt( ArgInfo, argv[i]);
// printf( "option added(%s)\n", argv[i]);
}else{
SA_insertName( ArgInfo, argv[i]);
// printf( "name added(%s)\n", argv[i]);
}
}
}
/*オプション文字列が存在すれば構造体のアドレスを返す*/
SAOptList* SA_IsThereOpt( SAArgInfo* ArgInfo, char* opt_name)
{
int i;
SAOptList* CurrentOptList;
CurrentOptList = ArgInfo->OptList;
for( i=0; i<(ArgInfo->opt_num); i++) {
if( strcmp( CurrentOptList->opt_name, opt_name) == 0) {
return( CurrentOptList);
}
CurrentOptList = CurrentOptList->next;
}
return( NULL);
}
/*引数の解析結果を表示する*/
void SA_printf( SAArgInfo* ArgInfo)
{
int i, j;
SAOptList* CurrentOptList;
SANameList* CurrentNameList;
CurrentOptList = (SAOptList*)(ArgInfo->OptList);
printf( "opt_num = %d\n", ArgInfo->opt_num);
for( i=0; i<(ArgInfo->opt_num); i++) {
CurrentNameList = (SANameList*)(CurrentOptList->NameList);
printf( "option[%s] ...", CurrentOptList->opt_name);
for( j=0; j<(CurrentOptList->name_num); j++) {
printf( " %s", CurrentNameList->name);
CurrentNameList = CurrentNameList->next;
}
printf( "\n");
CurrentOptList = CurrentOptList->next;
}
}
/**/
static void SA_insertOpt( SAArgInfo* ArgInfo, char* opt_name)
{
SAOptList DmyOptList;
SAOptList* CurrentOptList;
DmyOptList.next = ArgInfo->OptList;
CurrentOptList = &DmyOptList;
while( (CurrentOptList->next) != NULL) {
CurrentOptList = (SAOptList*)(CurrentOptList->next);
}
CurrentOptList->next = (SAOptList*)malloc( sizeof( SAOptList));
CurrentOptList = CurrentOptList->next;
/*--- 構築 ---*/
CurrentOptList->opt_name = opt_name;
CurrentOptList->name_num = 0;
CurrentOptList->NameList = NULL;
CurrentOptList->next = NULL;
/*------------*/
ArgInfo->opt_num++;
if( ArgInfo->OptList == NULL) {
ArgInfo->OptList = CurrentOptList;
}
}
/**/
static void SA_insertName( SAArgInfo* ArgInfo, char* name)
{
SAOptList DmyOptList;
SAOptList* CurrentOptList;
SANameList DmyNameList;
SANameList* CurrentNameList;
/*単独で見つかった場合はNULL文字のオプションに属させる*/
if( ArgInfo->OptList == NULL) {
SA_insertOpt( ArgInfo, opt_name_null);
}
DmyOptList.next = ArgInfo->OptList;
CurrentOptList = &DmyOptList;
while( (CurrentOptList->next) != NULL) {
CurrentOptList = (SAOptList*)(CurrentOptList->next);
}
DmyNameList.next = CurrentOptList->NameList;
CurrentNameList = &(DmyNameList);
while( (CurrentNameList->next) != NULL) {
CurrentNameList = (SANameList*)(CurrentNameList->next);
}
CurrentNameList->next = (SANameList*)malloc( sizeof( SANameList));
CurrentNameList = CurrentNameList->next;
CurrentNameList->name = name;
CurrentNameList->next = NULL;
CurrentOptList->name_num++;
if( CurrentOptList->NameList == NULL) {
CurrentOptList->NameList = CurrentNameList;
}
}
/*
void SA_searchopt( SAArgList* ArgList, int argc, char* argv[])
{
int i, j, k;
j = 0;
k = 0;
for( i=1; i<argc; i++) {
if( strncmp( argv[i], "-", 1) == 0) {
ArgList->opt[j] = malloc( strlen( argv[i])+1);
strcpy( ArgList->opt[j], argv[i]);
if( i+1 == argc) {
j++;
break;
}
if( strncmp( argv[i+1], "-", 1) != 0) {
i++;
ArgList->opt_arg[j] = malloc( strlen( argv[i])+1);
strcpy( ArgList->opt_arg[j], argv[i]);
}
j++;
}else{
ArgList->arg[k] = malloc( strlen( argv[i])+1);
strcpy( ArgList->arg[k], argv[i]);
k++;
}
}
ArgList->opt_num = j;
ArgList->arg_num = k;
printf( "argc num : %x\n", argc);
printf( "opt num : %x, arg num : %x\n", j, k);
for( i=0; i<j; i++) {
printf( "%s ... %s\n", ArgList->opt[i], ArgList->opt_arg[i]);
}
for( i=0; i<k; i++) {
printf( "%s\n", ArgList->arg[i]);
}
}
*/
void portoption( void)
{
// if( k != 2) {
printf( "error : too few input files.\n\n");
// }
}

55
tools/makelst/searcharg.h Normal file
View File

@ -0,0 +1,55 @@
#ifndef __SEARCH_ARG__
#define __SEARCH_ARG__
typedef struct
{
char* opt[7];
char* opt_arg[7];
char* arg[7];
int opt_num;
int arg_num;
}SAArgList;
/**/
typedef struct
{
void* next;
char* name;
}SANameList;
typedef struct
{
void* next;
char* opt_name;
SANameList* NameList;
int name_num;
}SAOptList;
typedef struct
{
SAOptList* OptList;
int opt_num;
}SAArgInfo;
/*引数を解析する*/
void SA_searchopt( SAArgInfo* ArgInfo, int argc, char* argv[]);
/*オプション文字列が存在すれば構造体のアドレスを返す*/
SAOptList* SA_IsThereOpt( SAArgInfo* ArgInfo, char* opt_name);
/*引数の解析結果を表示する*/
void SA_printf( SAArgInfo* ArgInfo);
//void SA_searchopt( SAArgList* ArgList, int argc, char* argv[]);
#endif /*__SEARCH_ARG__*/

228
tools/makelst/types.h Normal file
View File

@ -0,0 +1,228 @@
/*---------------------------------------------------------------------------*
Project: NitroSDK - - types definition
File: types.h
Copyright 2003-2006 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: types.h,v $
Revision 1.38 2006/03/17 00:33:54 yosizaki
support SDK_FORCE_EXPORT
Revision 1.37 2006/02/24 00:53:29 yosizaki
move position of SDK_INLINE definition.
Revision 1.36 2006/01/18 02:12:28 kitase_hirotake
do-indent
Revision 1.35 2005/11/14 05:17:25 okubata_ryoma
Revision 1.33 2005/09/05 01:39:14 yasu
SDK_BOOL_ALREADY_DEFINED_ 
Revision 1.32 2005/06/23 12:16:27 yasu
SDK_LITTLE_ENDIAN
Revision 1.31 2005/03/04 10:13:03 yasu
Revision 1.30 2005/03/01 01:57:00 yosizaki
copyright .
Revision 1.29 2005/02/28 05:26:02 yosizaki
do-indent.
Revision 1.28 2004/08/03 03:14:29 yasu
Fix comment
Revision 1.27 2004/05/14 11:57:44 takano_makoto
Add option SDK_HAS_NO_LONG_LONG_INT_ for environment of VC or BCB.
Revision 1.26 2004/04/23 04:24:14 yada
add comment for ATTRIBUTE_ALIGN
Revision 1.25 2004/04/23 04:14:31 yada
add ATTRIBUTE_ALIGN
Revision 1.24 2004/02/05 07:09:03 yasu
change SDK prefix iris -> nitro
Revision 1.23 2004/01/29 08:47:04 nishida_kenji
Change typedefs for better type check.
s32: signed int -> signed long
u32: unsigned int -> unsigned long
BOOL: s32 -> int
Revision 1.22 2004/01/05 04:11:16 nishida_kenji
add f32, vf32
Revision 1.21 2003/12/02 12:09:22 yasu
#<SPACE>
Revision 1.20 2003/11/27 06:35:17 yada
comment訂正
Revision 1.19 2003/11/11 09:14:41 nishida_kenji
RegTypeNNv型をtypedef
Revision 1.18 2003/11/11 06:10:18 nishida_kenji
gx/gxcommon.hに移動
Revision 1.17 2003/11/11 05:46:19 yada
BOOL, TRUE, FALSE INLINE, SDK_ASSERT()
Revision 1.16 2003/11/11 04:12:52 nishida_kenji
fx16rsの追加
Revision 1.15 2003/11/05 07:40:40 yasu
VecFx16 padding
Revision 1.14 2003/11/04 12:04:59 yasu
aligned   CW
Revision 1.13 2003/11/04 11:45:20 yasu
NULL
Revision 1.12 2003/11/04 09:37:03 yada
REG_BASE
Revision 1.11 2003/11/04 04:52:20 Nishida_Kenji
$NoKeywords: $
*---------------------------------------------------------------------------*/
#ifndef NITRO_TYPES_H_
#define NITRO_TYPES_H_
// Endian
#define SDK_LITTLE_ENDIAN
#define SDK_IS_LITTLE_ENDIAN 1
#define SDK_IS_BIG_ENDIAN 0
#ifdef SDK_ASM
#else //SDK_ASM
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char u8;
typedef unsigned short int u16;
typedef unsigned long u32;
#ifdef SDK_HAS_NO_LONG_LONG_INT_
typedef unsigned __int64 u64;
#else
typedef unsigned long long int u64;
#endif
typedef signed char s8;
typedef signed short int s16;
typedef signed long s32;
#ifdef SDK_HAS_NO_LONG_LONG_INT_
typedef signed __int64 s64;
#else
typedef signed long long int s64;
#endif
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
typedef float f32;
typedef volatile f32 vf32;
/*
io_register_list_XX.hで使用するマクロと型
*/
typedef u8 REGType8;
typedef u16 REGType16;
typedef u32 REGType32;
typedef u64 REGType64;
typedef vu8 REGType8v;
typedef vu16 REGType16v;
typedef vu32 REGType32v;
typedef vu64 REGType64v;
#ifndef SDK_BOOL_ALREADY_DEFINED_
#ifndef BOOL
typedef int BOOL;
#endif //BOOL
#endif //SDK_ALREAD_DEFINE_BOOL_
#ifndef TRUE
// Any non zero value is considered TRUE
#define TRUE 1
#endif //TRUE
#ifndef FALSE
#define FALSE 0
#endif // FALSE
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else // __cplusplus
#define NULL ((void *)0)
#endif // __cplusplus
#endif // NULL
// for compatibility with GAMECUBE
#if defined(SDK_CW) || defined(__MWERKS__)
#ifndef ATTRIBUTE_ALIGN
#define ATTRIBUTE_ALIGN(num) __attribute__ ((aligned(num)))
#endif
#endif
// Weak symbol
#if defined(SDK_CW) || defined(__MWERKS__)
#define SDK_WEAK_SYMBOL __declspec(weak)
#elif defined(SDK_PRODG)
#define SDK_WEAK_SYMBOL
#endif
/* option for the compiler which deals dead-strip */
#ifdef SDK_CW_FORCE_EXPORT_SUPPORT
#define SDK_FORCE_EXPORT __declspec(force_export)
#else
#define SDK_FORCE_EXPORT
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif //SDK_ASM
/* static inline を inline にして、コードサイズを削減したい場合は、マクロ SDK_INLINE を変更してください。
(static inline inline SDK_DECL_INLINE )
inline 使
inline static inline
使 static inline inline
FX_, VEC_, MTX_ */
#define SDK_INLINE static inline
#define SDK_DECL_INLINE static
/* NITRO_TYPES_H_ */
#endif

1
tools/makelst/version.h Normal file
View File

@ -0,0 +1 @@
#define SDK_DATE_OF_LATEST_FILE 20060905UL