1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - stripdebug
3   File:     stripdebug.c
4 
5   Copyright 2006-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include    <stdio.h>
18 #include    <stdlib.h>              // atoi()
19 #include    <ctype.h>
20 #include    <getopt.h>              // getopt()
21 #include    <string.h>
22 #include    "types.h"
23 #include    "elf.h"
24 #include    "elf_loader.h"
25 #include    "searcharg.h"
26 
27 
28 #define    DS_ROM_HEADER_SIZE    0x4000
29 
30 char*      input_elf_fname    = NULL;
31 char*      stripped_elf_fname = NULL;
32 char*      added_elf_fname    = NULL;
33 char       c_source_line_str[256];
34 
35 #define    STRIPPED_ELF_FILENAME    "stripped-"
36 #define    ADDED_ELF_FILENAME       "added-"
37 FILE*      NewElfFilep;
38 
39 /*---------------------------------------------------------------------------*
40  *
41  *---------------------------------------------------------------------------*/
42 u32 adr_ALIGN( u32 addr, u32 align_size);
43 void file_write( char* c_str, FILE* Fp);
44 
45 
46 /*---------------------------------------------------------------------------*
47  *
48  *---------------------------------------------------------------------------*/
49 u16        dbg_print_flag;
50 u16        unresolved_table_block_flag = 0;
51 
52 /*---------------------------------------------------------------------------*
53  *  MAIN
54  *---------------------------------------------------------------------------*/
55 
main(int argc,char * argv[])56 int main(int argc, char *argv[])
57 {
58     FILE        *FHp;
59     u32*        newelfbuf;
60 #if (SPECIAL_SECTION_ENABLE == 1) /*Add special section*/
61     u32*        dbgelfbuf;
62 #endif
63 //    u32*        aligned_newelfbuf;
64     u32         elfsize;
65     ELHandle    ElfH, ElfH2;
66     char*       elf_filename;
67     u32         elf_namesize;
68     char*       slash_pointer;
69     u16         result;
70 
71 
72 /*
73     for( i=0; i<argc; i++) {
74         fprintf(stdout, "%s\n", argv[i]);
75     }
76 */
77 
78     /*-----------------------------------------------------*/
79     dbg_print_flag = 0;
80     SA_searchopt( argc, argv);
81 
82     EL_Init();
83     unresolved_table_block_flag = 0;    //Release prohibition against adding to unresolved table
84 
85     /* Check the DLL */
86     FHp = fopen( input_elf_fname, "rb");
87     if( FHp == NULL) {
88         printf( "cannot open file \"%s\".\n", input_elf_fname);
89         exit( 1);
90     }
91     fseek( FHp, 0, SEEK_END);
92     elfsize = ftell( FHp);
93     fseek( FHp, 0, SEEK_SET);
94 
95     printf( "input elf size    = 0x%x\n", (int)elfsize);
96 
97     EL_InitHandle( &ElfH);
98     EL_InitHandle( &ElfH2);
99 
100 //    aligned_newelfbuf = (((u32)newelfbuf) & (~0x20)) + 0x20; //0x20 bytes align
101     newelfbuf = (u32*)malloc( elfsize);
102     result = EL_LoadLibraryfromFile( &ElfH,  FHp, newelfbuf, 0);
103 
104 #if (SPECIAL_SECTION_ENABLE == 1) /*Add special section*/
105     dbgelfbuf = (u32*)malloc( elfsize * 2);
106     result = EL_LoadLibraryfromFile( &ElfH2,  FHp, dbgelfbuf, 1);
107 #endif
108 
109     fclose( FHp);
110 //    EL_ResolveAllLibrary();
111 
112 
113     /*---------------------------------------------*/
114     /*If there is an -o option, change to specified filename*/
115     if( stripped_elf_fname != NULL) {
116         elf_filename = stripped_elf_fname;
117     }else{
118         /*Generate elf filename*/
119         elf_namesize = strlen( STRIPPED_ELF_FILENAME) + strlen( input_elf_fname) + 1;//+1 is the last null character
120         elf_filename = malloc( elf_namesize);
121         memset( elf_filename, 0, elf_namesize);
122 
123         slash_pointer = strrchr( input_elf_fname, '/');
124         if( slash_pointer == NULL) {                      //When there is no slash
125             strcpy( elf_filename, STRIPPED_ELF_FILENAME); //Prefix
126             strcat( elf_filename, input_elf_fname);       //Filename
127         }else{                                            //When there is a slash
128             memcpy( elf_filename, input_elf_fname, (slash_pointer - input_elf_fname)+1);
129             strcat( elf_filename, STRIPPED_ELF_FILENAME);
130             strcat( elf_filename, slash_pointer+1);
131         }
132     }
133 
134     NewElfFilep = fopen( elf_filename, "wb");
135     if( !NewElfFilep) {
136         printf( "error : cannot create file \"%s\".\n\n", elf_filename);
137         exit( 1);
138     }
139 
140     printf( "stripped elf size = 0x%x\n", (int)(ElfH.newelf_size));
141     fwrite( newelfbuf, 1, ElfH.newelf_size, NewElfFilep);
142 
143     fclose( NewElfFilep);
144     free( newelfbuf);
145     printf( "stripped elf file \"%s\" is generated.\n\n", elf_filename);
146     if( stripped_elf_fname == NULL) {    //If there is no -o option, this is deallocated because of malloc
147         free( elf_filename);
148     }
149     /*---------------------------------------------*/
150 
151 
152 
153     /*---------------------------------------------*/
154 #if (SPECIAL_SECTION_ENABLE == 1) /*Add special section*/
155     /*If there is an -O option, change to specified filename*/
156     if( added_elf_fname != NULL) {
157         elf_filename = added_elf_fname;
158     }else{
159         /*Generate elf filename*/
160         elf_namesize = strlen( ADDED_ELF_FILENAME) + strlen( input_elf_fname) + 1;//+1 is the last null character
161         elf_filename = malloc( elf_namesize);
162         memset( elf_filename, 0, elf_namesize);
163 
164         slash_pointer = strrchr( input_elf_fname, '/');
165         if( slash_pointer == NULL) {                      //When there is no slash
166             strcpy( elf_filename, ADDED_ELF_FILENAME);    //Prefix
167             strcat( elf_filename, input_elf_fname);       //Filename
168         }else{                                            //When there is a slash
169             memcpy( elf_filename, input_elf_fname, (slash_pointer - input_elf_fname)+1);
170             strcat( elf_filename, ADDED_ELF_FILENAME);
171             strcat( elf_filename, slash_pointer+1);
172         }
173     }
174 
175     NewElfFilep = fopen( elf_filename, "wb");
176     if( !NewElfFilep) {
177         printf( "error : cannot create file \"%s\".\n\n", elf_filename);
178         exit( 1);
179     }
180 
181     printf( "added elf size = 0x%x\n", (int)(ElfH2.newelf_size));
182     fwrite( dbgelfbuf, 1, ElfH2.newelf_size, NewElfFilep);
183 
184     fclose( NewElfFilep);
185     free( dbgelfbuf);
186     printf( "added elf file \"%s\" is generated.\n\n", elf_filename);
187     if( added_elf_fname == NULL) {    //If there is no -o option, this is deallocated because of malloc
188         free( elf_filename);
189     }
190 #endif
191     /*---------------------------------------------*/
192 
193     exit( 0);
194 
195     /*-----------------------------------------------------*/
196 
197     return 0;
198 }
199 
200 /*---------------------------------------------------------------------------*
201  *  Align addresses
202  *---------------------------------------------------------------------------*/
adr_ALIGN(u32 addr,u32 align_size)203 u32 adr_ALIGN( u32 addr, u32 align_size)
204 {
205     u32 aligned_addr;
206 
207     if( (addr % align_size) == 0) {
208         aligned_addr = addr;
209     }else{
210         aligned_addr = (((addr) & ~((align_size) - 1)) + (align_size));
211     }
212 
213     return aligned_addr;
214 }
215 
216 /*---------------------------------------------------------------------------*
217  *  Write string to file
218  *---------------------------------------------------------------------------*/
file_write(char * c_str,FILE * Fp)219 void file_write( char* c_str, FILE* Fp)
220 {
221     fwrite( c_str, 1, strlen( c_str), Fp);
222 }
223