add stripdebug tool

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@161 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
shirait 2007-07-03 01:56:37 +00:00
parent 9694d4441e
commit 45684e38f1
15 changed files with 3232 additions and 0 deletions

48
tools/stripdebug/Makefile Normal file
View File

@ -0,0 +1,48 @@
#! make -f
#---------------------------------------------------------------------------
# Project: NitroSDK - tools - stripdebug
# 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 = stripdebug.exe
SOURCES_C = stripdebug.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/stripdebug/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/stripdebug/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_*/

340
tools/stripdebug/elf.c Normal file
View File

@ -0,0 +1,340 @@
#include "types.h"
#include "elf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.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/stripdebug/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_ */

View File

@ -0,0 +1,882 @@
/*---------------------------------------------------------------------------*
Project: TWL - 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 "types.h"
#include "elf.h"
#include "elf_loader.h"
#include "arch.h"
#include "loader_subset.h"
#include <string.h>
#include <stdlib.h>
//OSHeapHandle EL_Heap;
ELAdrEntry* ELAdrEntStart = NULL;
ELUnresolvedEntry* ELUnrEntStart = NULL;
extern u16 dbg_print_flag;
extern u32 unresolved_table_block_flag;
extern u32 ELi_ALIGN( u32 addr, u32 align_size);
#define MAKELST_DS_API " elAddAdrEntry" //DS上でアドレステーブルに追加するAPI関数名
extern char c_source_line_str[256];
extern FILE* NewElfFilep;
/*------------------------------------------------------
-----------------------------------------------------*/
// 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);
/*hex値を10進の文字列で表現する*/
void ELi_SetDecSize( char* dec, u32 hex)
{
u16 i;
u32 tmp = 1000000000;
u16 ptr = 0;
memset( dec, 0x20, 10);
for( i=0; i<10; i++) {
if( ((hex / tmp) != 0) || (ptr != 0)) {
dec[ptr++] = 0x30 + (hex/tmp);
hex -= (hex/tmp) * tmp;
}
tmp /= 10;
}
}
/*---------------------------------------------------------
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 new_image_pointer;
u32 arch_size;
u32 elf_num = 0; /*ELFオブジェクトの数*/
u32 newarch_size = 0;
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; /*最初のエントリへ*/
new_image_pointer = (u32)buf;
memcpy( buf, OBJMAG, 8); //stripped elfにコピー
new_image_pointer += 8;
newarch_size += 8;
ElfHandle->buf_current = new_image_pointer;
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++;
ElfHandle->ELi_ReadStub( new_image_pointer, ElfHandle->FileStruct, (u32)(obj_image),
image_pointer, arch_size); //arヘッダをstripped elfにコピー
result = ELi_LoadObject( ElfHandle, (void*)(image_pointer+arch_size),
new_image_pointer + arch_size);
// (ElfHandle->buf_current + arch_size));
ELi_SetDecSize( (char*)(((ArchHdr*)new_image_pointer)->ar_size), ElfHandle->newelf_size); //archヘッダのサイズ更新
new_image_pointer += (ElfHandle->newelf_size + arch_size);
newarch_size += (ElfHandle->newelf_size + arch_size);
if( result < all_result) { /*悪い結果のときだけall_resultに反映*/
all_result = result;
}
/*初期値の設定*/
ElfHandle->ShdrEx = NULL;
ElfHandle->SymEx = NULL;
ElfHandle->process = EL_INITIALIZED; /*フラグの設定*/
}else{
ElfHandle->ELi_ReadStub( new_image_pointer, ElfHandle->FileStruct, (u32)(obj_image),
image_pointer, arch_size+AR_GetEntrySize( &ArHdr)); //arヘッダとエントリをstripped elfにコピー
new_image_pointer += (AR_GetEntrySize( &ArHdr) + arch_size);
newarch_size += (AR_GetEntrySize( &ArHdr) + arch_size);
}
/*次のエントリへ*/
ElfHandle->ELi_ReadStub( &ArHdr, ElfHandle->FileStruct, (u32)(obj_image), image_pointer, arch_size);
image_pointer += arch_size + AR_GetEntrySize( &ArHdr);
}
ElfHandle->newelf_size = newarch_size;
}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; //デバッグプリント用
u32 newelf_shoff = 0; //stripped elfイメージへの書き込みポインタ
u32 buf_shdr;
u32 section_num = 0;
u32 newelf_size;
u32 tmp_buf;
u32 *shdr_table; //セクションヘッダ新旧番号対応テーブル
u32 *sym_table; //シンボルエントリ新旧番号対応テーブル
/* 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 = (u32)buf + sizeof( Elf32_Ehdr);
ElfHandle->shentsize = ElfHandle->CurrentEhdr.e_shentsize;
/*セクションヘッダテーブル構築*/
shdr_table = (u32*)malloc( 4 * ElfHandle->CurrentEhdr.e_shnum);
/*---------- ELShdrExのリストとshdr_tableを作る ----------*/
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;
shdr_table[i] = 0xFFFFFFFF;
}else{ /*デバッグ情報でない場合*/
/*セクションヘッダをコピー*/
ELi_GetShdr( ElfHandle, i, &(CurrentShdrEx->Shdr));
CurrentShdrEx->debug_flag = 0;
shdr_table[i] = section_num; /*セクション新旧テーブル作成*/
// printf( "shdr_table[0x%x] = 0x%x\n", i, section_num);
section_num++;
/*セクション文字列を取得しておく*/
CurrentShdrEx->str = (char*)malloc( 128); //128文字バッファ取得
ELi_GetStrAdr( ElfHandle, ElfHandle->CurrentEhdr.e_shstrndx,
CurrentShdrEx->Shdr.sh_name,
CurrentShdrEx->str, 128);
}
}
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 = ELi_ALIGN( (u32)(ElfHandle->buf_current), 4);
/* 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));
}*/
//シンボルテーブルセクション
else if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
ELi_BuildSymList( ElfHandle, i, &(CurrentShdrEx->sym_table)); //シンボルリスト作成
{
ELSymEx* CurrentSymEx;
ELShdrEx* StrShEx; //文字列セクション
char symstr[128];
u32 symbol_num = 0;
/*--- シンボルエントリのデータを修正 ---*/
CurrentSymEx = ElfHandle->SymEx;
while( CurrentSymEx != NULL) { //SymExをたどればデバッグシンボルは含まれない
/*文字列セクション取得*/
StrShEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
CurrentShdrEx->Shdr.sh_link);
/*--- 文字列セクションの中身構築 ---*/
ELi_GetStrAdr( ElfHandle, CurrentShdrEx->Shdr.sh_link, //シンボル文字列取得
CurrentSymEx->Sym.st_name,
symstr, 128);
StrShEx->str_table = realloc( StrShEx->str_table, //シンボル文字列追加
(StrShEx->str_table_size) +
strlen( symstr) + 1);
strcpy( (u8*)((u32)StrShEx->str_table + StrShEx->str_table_size),
symstr);
CurrentSymEx->Sym.st_name = StrShEx->str_table_size; //シンボルエントリのデータを修正
StrShEx->str_table_size += ( strlen( symstr) + 1);
/*---------------------------------*/
symbol_num++;
CurrentSymEx->Sym.st_shndx = shdr_table[CurrentSymEx->Sym.st_shndx]; //シンボルエントリの対象セクション番号更新
CurrentSymEx = CurrentSymEx->next;
}/*-------------------------------------*/
/*--- シンボルテーブルセクションヘッダの更新 ---*/
CurrentShdrEx->loaded_adr = ELi_CopySymToBuffer( ElfHandle);
CurrentShdrEx->Shdr.sh_link = shdr_table[CurrentShdrEx->Shdr.sh_link]; //文字列セクション番号更新
CurrentShdrEx->Shdr.sh_size = symbol_num * sizeof( Elf32_Sym);
/*----------------------------------------------*/
}
ELi_FreeSymList( ElfHandle, CurrentShdrEx->sym_table); //シンボルリスト開放
}
/* printf( "section %02x relocated at %08x\n",
i, CurrentShdrEx->loaded_adr);*/
}
}
/*---------- REL, RELA, STRTABセクションの処理 ----------*/
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
//
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { //デバッグ情報の場合
}else{ //デバッグ情報でない場合
//RELセクション
if( CurrentShdrEx->Shdr.sh_type == SHT_REL) {
CurrentShdrEx->loaded_adr = (u32)
ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
{
Elf32_Rel* CurrentRel;
ELShdrEx* SymShdrEx;
u32 new_sym_num;
/*シンボルセクション取得*/
SymShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
CurrentShdrEx->Shdr.sh_link);
/*コピー先のRelセクションを修正*/
for( j=0; j<(CurrentShdrEx->Shdr.sh_size/CurrentShdrEx->Shdr.sh_entsize); j++) {
CurrentRel = (Elf32_Rel*)(CurrentShdrEx->loaded_adr + (j * sizeof( Elf32_Rel)));
new_sym_num = SymShdrEx->sym_table[ELF32_R_SYM(CurrentRel->r_info)];
CurrentRel->r_info = ELF32_R_INFO( new_sym_num,
ELF32_R_TYPE(CurrentRel->r_info));
}
}
}
//RELAセクション
else if( CurrentShdrEx->Shdr.sh_type == SHT_RELA) {
CurrentShdrEx->loaded_adr = (u32)
ELi_CopySectionToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
{
Elf32_Rela* CurrentRela;
ELShdrEx* SymShdrEx;
u32 new_sym_num;
/*シンボルセクション取得*/
SymShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx,
CurrentShdrEx->Shdr.sh_link);
/*コピー先のRelaセクションを修正*/
for( j=0; j<(CurrentShdrEx->Shdr.sh_size/CurrentShdrEx->Shdr.sh_entsize); j++) {
CurrentRela = (Elf32_Rela*)(CurrentShdrEx->loaded_adr + (j * sizeof( Elf32_Rela)));
// printf( "symnum: 0x%x\n", ELF32_R_SYM(CurrentRela->r_info));
// printf( "sym_table:0x%x", (u32)(SymShdrEx->sym_table));
new_sym_num = SymShdrEx->sym_table[ELF32_R_SYM(CurrentRela->r_info)];
CurrentRela->r_info = ELF32_R_INFO( new_sym_num,
ELF32_R_TYPE(CurrentRela->r_info));
}
}
}
//文字列テーブルセクション
else if( CurrentShdrEx->Shdr.sh_type == SHT_STRTAB) {
if( i == ElfHandle->CurrentEhdr.e_shstrndx) { //セクション名文字列テーブルセクション
CurrentShdrEx->loaded_adr = (u32)
ELi_CopyShStrToBuffer( ElfHandle, &(CurrentShdrEx->Shdr));
}else{
CurrentShdrEx->loaded_adr = (u32)
ELi_CopySymStrToBuffer( ElfHandle, CurrentShdrEx);
// printf( "sym str section:0x%x, size:0x%x\n", i, CurrentShdrEx->str_table_size);
}
}
}
}
/*-------------------------------------------------------*/
/*ここまででセクションの中身だけがstripped elfにコピーされた*/
/*---------- セクションヘッダを stripped elfにコピー ----------*/
buf_shdr = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
ElfHandle->buf_current = buf_shdr;
// printf( "buf_shdr = 0x%x\n", buf_shdr);
// printf( "buf = 0x%x\n", (u32)buf);
newelf_shoff = buf_shdr - ((u32)(buf));
// printf( "newelf_shoff = 0x%x\n", newelf_shoff);
section_num = 0;
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
//
tmp_buf = buf_shdr + ( section_num * sizeof( Elf32_Shdr));
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) { //デバッグ情報の場合はNULLセクションに変換
// memset( (u8*)tmp_buf, '\0', sizeof( Elf32_Shdr));
}else{
/*オフセット更新*/
if( CurrentShdrEx->loaded_adr != 0) {
CurrentShdrEx->Shdr.sh_offset = (CurrentShdrEx->loaded_adr - (u32)buf);
}
/*セクションヘッダをstripped elfイメージへコピー*/
CurrentShdrEx->Shdr.sh_link = shdr_table[CurrentShdrEx->Shdr.sh_link]; //セクション番号更新
if( CurrentShdrEx->Shdr.sh_type == SHT_SYMTAB) {
/*シンボルテーブルのsh_typeはシンボルエントリのインデックスを表す*/
}else{
CurrentShdrEx->Shdr.sh_info = shdr_table[CurrentShdrEx->Shdr.sh_info]; //セクション番号更新
}
memcpy( (u8*)tmp_buf, &(CurrentShdrEx->Shdr),
sizeof( Elf32_Shdr));
section_num++; /*セクション数更新*/
}
}
// コピー終了後
ElfHandle->process = EL_COPIED;
/*------------------------------------------------------------*/
ElfHandle->newelf_size = (buf_shdr - (u32)buf) + (section_num*sizeof( Elf32_Shdr));
// printf( "newelf_size = 0x%x\n", ElfHandle->newelf_size);
/*---------- ELFヘッダ更新 ----------*/
ElfHandle->CurrentEhdr.e_shnum = section_num; /*減ったセクション数をELFヘッダに反映*/
ElfHandle->CurrentEhdr.e_shstrndx = shdr_table[ElfHandle->CurrentEhdr.e_shstrndx];
//セクションヘッダオフセット更新
ElfHandle->CurrentEhdr.e_shoff = newelf_shoff;
memcpy( (u8*)buf, &(ElfHandle->CurrentEhdr), sizeof( Elf32_Ehdr)); /*ELFヘッダをstripped elfイメージにコピー*/
/*-----------------------------------*/
/*---------- 再配置 ----------*/
/* 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", num_of_entry);
printf( "Section Header Info.\n");
printf( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
printf( "info : %x\n", 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 ", ElfHandle->Rel.r_offset);
printf( "%08x ", ElfHandle->Rel.r_info);
printf( " ");
printf( "%08x ", 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", num_of_entry);
printf( "Section Header Info.\n");
printf( "link : %x\n", CurrentShdrEx->Shdr.sh_link);
printf( "info : %x\n", 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 ", ElfHandle->Rela.r_offset);
printf( "%08x ", ElfHandle->Rela.r_info);
printf( " ");
printf( "%08x ", 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, 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, 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;
}
/*------------------------------------------------------
-----------------------------------------------------*/
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);
}
/*------------------------------------------------------
-----------------------------------------------------*/
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;
}
/*------------------------------------*/
}
/*------------------------------------------------------
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);
}

View File

@ -0,0 +1,199 @@
/*---------------------------------------------------------------------------*
Project: TWL - ELF Loader
File: elf_loader.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef _ELF_LOADER_H_
#define _ELF_LOADER_H_
#include <stdio.h>
#include "types.h"
#include "elf.h"
/*------------------------------------------------------
()
-----------------------------------------------------*/
typedef struct {
void* next;
u16 index;
u16 debug_flag; /*0:デバッグ情報でない、1:デバッグ情報*/
u32 loaded_adr;
u32 alloc_adr;
u32 loaded_size;
Elf32_Shdr Shdr;
char* str; /*セクション名文字列をコピーしてきたもの*/
u32* sym_table; /*シンボルセクションのとき有効な新旧対応表*/
void* str_table; /*STRセクションのとき有効新文字列テーブル*/
u32 str_table_size; /*STRセクションのとき有効新文字列テーブルのサイズ*/
}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リストの先頭 */
ELSymEx** SymExTbl; /* SymExアドレスのテーブル全シンボル数ぶん*/
u32 SymExTarget; /* SymExリストを構築したシンボルセクションのセクション番号 */
ELi_ReadFunc ELi_ReadStub; /* リードスタブ関数 */
void* FileStruct; /* ファイル構造体 */
u32 mem_adr; /*最初にロードされたセクションのsh_addrが入る(DSのROMヘッダ用パラメータ)*/
u32 newelf_size;
}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,580 @@
/*---------------------------------------------------------------------------*
Project: TWL - 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))
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_CopySymStrToBuffer( ELHandle* ElfHandle, ELShdrEx* SymStrShdrEx)
{
u32 load_start, i;
/*アラインメントをとる*/
load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
memcpy( load_start, SymStrShdrEx->str_table, SymStrShdrEx->str_table_size);
/*セクションヘッダのサイズ修正*/
SymStrShdrEx->Shdr.sh_size = SymStrShdrEx->str_table_size;
/*バッファポインタを移動*/
ElfHandle->buf_current = (void*)(load_start + SymStrShdrEx->str_table_size);
return( void*)load_start;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopyShStrToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr)
{
u32 load_start, i;
u32 total_size = 0;
ELShdrEx* CurrentShdrEx;
/*アラインメントをとる*/
load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
// load_adr = load_start;
for( i=0; i<(ElfHandle->CurrentEhdr.e_shnum); i++) {
CurrentShdrEx = ELi_GetShdrExfromList( ElfHandle->ShdrEx, i);
if( CurrentShdrEx->debug_flag == 1) {
}else{
CurrentShdrEx->Shdr.sh_name = total_size;
strcpy( load_start+total_size, CurrentShdrEx->str);
total_size += (strlen( CurrentShdrEx->str) + 1);
}
}
/*セクションヘッダのサイズ修正*/
Shdr->sh_size = total_size;
/*バッファポインタを移動*/
ElfHandle->buf_current = (void*)(load_start + total_size);
return( void*)load_start;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopySymToBuffer( ELHandle* ElfHandle)
{
u32 load_start, load_adr;
u32 total_size = 0;
ELSymEx* CurrentSymEx;
/*アラインメントをとる*/
load_start = ELi_ALIGN( ((u32)(ElfHandle->buf_current)), 4);
load_adr = load_start;
CurrentSymEx = ElfHandle->SymEx;
while( CurrentSymEx != NULL) {
/*コピー*/
memcpy( (u8*)load_adr, &(CurrentSymEx->Sym),
sizeof( Elf32_Sym));
CurrentSymEx = CurrentSymEx->next;
load_adr += sizeof( Elf32_Sym);
total_size += sizeof( Elf32_Sym);
// printf( "symbol found\n");
}
/*バッファポインタを移動*/
ElfHandle->buf_current = (void*)(load_start + total_size);
return( void*)load_start;
}
/*------------------------------------------------------
-----------------------------------------------------*/
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);
}
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_BuildSymList( ELHandle* elElfDesc, u32 symsh_index, u32** sym_table)
{
u32 i;
u32 num_of_sym; //シンボルの全体数
u16 debug_flag;
Elf32_Sym TestSym;
ELSymEx* CurrentSymEx;
ELShdrEx* CurrentShdrEx;
Elf32_Shdr SymShdr;
ELSymEx DmySymEx;
u32 sym_num = 0;
if( elElfDesc->SymExTarget == symsh_index) {
// printf( "%s skip.\n", __FUNCTION__);
return; //既にリスト作成済み
}else{
ELi_FreeSymList( elElfDesc, sym_table); /*シンボルリストを開放する*/
}
// printf( "%s build\n", __FUNCTION__);
/*SYMTABセクションヘッダ取得*/
ELi_GetShdr( elElfDesc, symsh_index, &SymShdr);
/*シンボル新旧対応テーブル構築*/
*sym_table = (u32*)malloc( 4 * (SymShdr.sh_size / SymShdr.sh_entsize));
num_of_sym = (SymShdr.sh_size) / (SymShdr.sh_entsize); //シンボルの全体数
elElfDesc->SymExTbl = malloc( num_of_sym * 4);
/*---------- ElSymExのリストを作る ----------*/
CurrentSymEx = &DmySymEx;
for( i=0; i<num_of_sym; i++) {
/*シンボルエントリをコピー*/
ELi_GetEntry( elElfDesc, &SymShdr, i, &TestSym);
/*-- デバッグ情報フラグをセット --*/
CurrentShdrEx = ELi_GetShdrExfromList( elElfDesc->ShdrEx, TestSym.st_shndx);
if( CurrentShdrEx) {
debug_flag = CurrentShdrEx->debug_flag;
}else{
debug_flag = 0;
}/*-------------------------------*/
if( debug_flag == 1) {
elElfDesc->SymExTbl[i] = NULL;
(*sym_table)[i] = 0xFFFFFFFF;
}else{
CurrentSymEx->next = malloc( sizeof(ELSymEx));
CurrentSymEx = (ELSymEx*)(CurrentSymEx->next);
memcpy( &(CurrentSymEx->Sym), &TestSym, sizeof(TestSym));
elElfDesc->SymExTbl[i] = CurrentSymEx;
(*sym_table)[i] = sym_num;
sym_num++;
// printf( "sym_no: %02x ... st_shndx: %04x\n", i, CurrentSymEx->Sym.st_shndx);
/*-- ElSymExのThumbフラグをセット関数シンボルだけ必要--*/
if( ELF32_ST_TYPE( CurrentSymEx->Sym.st_info) == STT_FUNC) {
CurrentSymEx->thumb_flag = (u16)(ELi_CodeIsThumb( elElfDesc, CurrentSymEx->Sym.st_shndx,
CurrentSymEx->Sym.st_value));
}else{
CurrentSymEx->thumb_flag = 0;
}/*--------------------------------------------------------*/
}
}
CurrentSymEx->next = NULL;
elElfDesc->SymEx = DmySymEx.next;
/*-------------------------------------------*/
elElfDesc->SymExTarget = symsh_index;
}
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_FreeSymList( ELHandle* elElfDesc, u32** sym_table)
{
ELSymEx* CurrentSymEx;
ELSymEx* FwdSymEx;
if( elElfDesc->SymExTbl != NULL) {
free( elElfDesc->SymExTbl);
elElfDesc->SymExTbl = NULL;
}
/*------- ElSymExのリストを解放する -------*/
CurrentSymEx = elElfDesc->SymEx;
if( CurrentSymEx) {
while( CurrentSymEx->next != NULL) {
FwdSymEx = CurrentSymEx;
CurrentSymEx = CurrentSymEx->next;
free( FwdSymEx);
}
elElfDesc->SymEx = NULL;
}
/*-----------------------------------------*/
/* if( *sym_table) { //ここはアプリケーションで開放させるのでコメントアウト
free( *sym_table);
}*/
elElfDesc->SymExTarget = 0xFFFFFFFF;
}
/*------------------------------------------------------
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,160 @@
/*---------------------------------------------------------------------------*
Project: TWL - ELF Loader
File: loader_subset.h
Copyright 2006,2007 Nintendo. All rights reserved.
These coded instructions, statements, and computer programs contain
proprietary information of Nintendo of America Inc. and/or Nintendo
Company Ltd., and are protected by Federal copyright law. They may
not be disclosed to third parties or copied or duplicated in any form,
in whole or in part, without the prior written consent of Nintendo.
*---------------------------------------------------------------------------*/
#ifndef _LOADER_SUBSET_H_
#define _LOADER_SUBSET_H_
#include "types.h"
#include "elf.h"
#include "elf_loader.h"
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopySymStrToBuffer( ELHandle* ElfHandle, ELShdrEx* SymStrShdrEx);
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopyShStrToBuffer( ELHandle* ElfHandle, Elf32_Shdr* Shdr);
/*------------------------------------------------------
-----------------------------------------------------*/
void* ELi_CopySymToBuffer( ELHandle* ElfHandle);
/*------------------------------------------------------
-----------------------------------------------------*/
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_BuildSymList( ELHandle* elElfDesc, u32 symsh_index, u32** sym_table);
/*------------------------------------------------------
-----------------------------------------------------*/
void ELi_FreeSymList( ELHandle* elElfDesc, u32** sym_table);
/*------------------------------------------------------
-----------------------------------------------------*/
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_*/

View File

@ -0,0 +1,21 @@
・stripdebug
elfファイルからデバッグ情報を削除します。
具体的には、以下の情報を削除します。
・デバッグセクションのセクションヘッダ
・デバッグセクションの中身
・シンボルセクションのデバッグシンボルエントリ
・セクション文字列テーブルの中のデバッグセクション用文字列エントリ
・シンボル文字列テーブルの中のデバッグシンボル用文字列エントリ
stripコマンドとの相違点は次の通りです。
・セクションを並び換えない
・セクションの先頭アドレスを示すシンボルを生成しない
・セクション文字列テーブルおよびシンボル文字列テーブルの文字列を
 重複して参照しない
・元ファイルにセクション対応テーブルをスペシャルセクションとして
 追加する(未実装)

View File

@ -0,0 +1,61 @@
#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;
*/
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");
// }
}

View File

@ -0,0 +1,21 @@
#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;
void SA_searchopt( SAArgList* ArgList, int argc, char* argv[]);
#endif /*__SEARCH_ARG__*/

View File

@ -0,0 +1,202 @@
/*---------------------------------------------------------------------------*
Project: tools - makedsrom
File: stripdebug.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 <ctype.h>
#include <getopt.h> // getopt()
#include <string.h>
#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 STRIPPED_ELF_FILENAME "stripped-"
FILE* NewElfFilep;
/*---------------------------------------------------------------------------*
*
*---------------------------------------------------------------------------*/
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, j, k;
int n;
int narg;
int t;
FILE *FHp;
u32 *elfbuf;
u32* newelfbuf;
u32 elfsize;
u32 mainp_malloc_size, subp_malloc_size;
size_t filesize;
ELHandle ElfH;
u32 loadstart, loadend, loadsize, ramadr;
u32 entry_address, ram_address;
u32 sub_loadstart, sub_loadend, sub_loadsize, sub_ramadr;
u32 sub_entry_address, sub_ram_address;;
u32 header_buf[DS_ROM_HEADER_SIZE/4];
char* elf_filename;
u32 elf_namesize;
char* slash_pointer;
SAArgList ArgList;
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( &ArgList, argc, argv);
/*オプションが少ないとき*/
if( argc == 1) {
printf( "Development Tool - stripdebug - strip debug-section from armelf.\n");
printf( "Build %s\n\n", __DATE__);
printf( "Usage: stripdebug [-o output-file] dll-file\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);
}
}
}
EL_Init();
unresolved_table_block_flag = 0; //Unresolvedテーブルへの追加禁止を解除
/* dllファイルを調べる */
FHp = fopen( ArgList.arg[0], "rb");
if( FHp == NULL) {
printf( "cannot open file \"%s\".\n", ArgList.arg[0]);
exit( 1);
}
fseek( FHp, 0, SEEK_END);
elfsize = ftell( FHp);
fseek( FHp, 0, SEEK_SET);
newelfbuf = (u32*)malloc( elfsize);
printf( "input elf size = 0x%x\n", elfsize);
EL_InitHandle( &ElfH);
result = EL_LoadLibraryfromFile( &ElfH, FHp, newelfbuf);
fclose( FHp);
// EL_ResolveAllLibrary();
/*---------------------------------------------*/
/*仮のelfファイル名生成*/
elf_namesize = strlen( STRIPPED_ELF_FILENAME) + strlen( ArgList.arg[0]) + 1;//+1は最後のnull文字
elf_filename = malloc( elf_namesize);
memset( elf_filename, 0, elf_namesize);
slash_pointer = strrchr( ArgList.arg[0], '/');
if( slash_pointer == NULL) { //スラッシュがない場合
strcpy( elf_filename, STRIPPED_ELF_FILENAME); //接頭語
strcat( elf_filename, ArgList.arg[0]); //ファイル名
}else{ //スラッシュがある場合
memcpy( elf_filename, ArgList.arg[0], (slash_pointer - ArgList.arg[0])+1);
strcat( elf_filename, STRIPPED_ELF_FILENAME);
strcat( elf_filename, slash_pointer+1);
}
/*-o オプションがあれば指定ファイル名に変更*/
for( i=0; i<ArgList.opt_num; i++) {
if( strcmp( ArgList.opt[i], "-o") == 0) {
if( ArgList.opt_arg[i] != NULL) {
elf_filename = ArgList.opt_arg[i];
break;
}else{
printf( "error : no filename after \"-o\" option.\n\n");
exit( 1);
}
}
}
NewElfFilep = fopen( elf_filename, "wb");
if( !NewElfFilep) {
printf( "error : cannot create file \"%s\".\n\n", elf_filename);
exit( 1);
}
printf( "stripped elf size = 0x%x\n", ElfH.newelf_size);
fwrite( newelfbuf, 1, ElfH.newelf_size, NewElfFilep);
fclose( NewElfFilep);
/*---------------------------------------------*/
printf( "stripped elf file \"%s\" is generated.\n\n", elf_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);
}

228
tools/stripdebug/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

View File

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