1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - bin2obj
3 File: output.c
4
5 Copyright 2005–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-18#$
14 $Rev: 8573 $
15 $Author: okubata_ryoma $
16 *---------------------------------------------------------------------------*/
17 #include "bin2obj.h"
18
19 static BOOL output_region(FILE * fp, u32 offset, const u8 *ptr, u32 size);
20
21 /*---------------------------------------------------------------------------*
22 Name: output_object
23
24 Description: Output object to file
25
26 Arguments: obj Object information
27 filename Output file name
28
29 Returns: None.
30 *---------------------------------------------------------------------------*/
output_object(const Object * obj,const char * filename)31 BOOL output_object(const Object * obj, const char *filename)
32 {
33 FILE *fp;
34 u32 i, n;
35 u32 offset;
36 u32 size;
37 u8 *ptr;
38 Object const *cooked_obj;
39 Object object;
40
41 if (NULL == (fp = fopen(filename, "wb")))
42 {
43 fprintf(stderr, "Error: Cannot open file %s.\n", filename);
44 return FALSE;
45 }
46
47 if (obj->header.e_ident[5] == ELFDATA2MSB)
48 {
49 // Big Endian: Clone & Swap byte order
50 conv_to_big_endian(obj, &object);
51 cooked_obj = &object;
52 }
53 else
54 {
55 // Little Endian: Just make shortcut
56 cooked_obj = obj;
57 }
58
59 // Elf Header
60 offset = 0;
61 size = obj->header.e_ehsize;
62 ptr = (u8 *)&cooked_obj->header;
63 if (!output_region(fp, offset, ptr, size))
64 {
65 return FALSE;
66 }
67
68 // Section Header
69 offset = obj->header.e_shoff;
70 size = obj->header.e_shentsize * obj->header.e_shnum;
71 ptr = (u8 *)&cooked_obj->section[0];
72 if (!output_region(fp, offset, ptr, size))
73 {
74 return FALSE;
75 }
76
77 // Section: ShStrTab
78 n = obj->header.e_shstrndx;
79 offset = obj->section[n].sh_offset;
80 size = obj->section[n].sh_size;
81 ptr = (u8 *)obj->section_name.ptr;
82 if (!output_region(fp, offset, ptr, size))
83 {
84 return FALSE;
85 }
86
87 // Section: Symbol
88 n = obj->symbol_index;
89 offset = obj->section[n].sh_offset;
90 size = obj->section[n].sh_size;
91 ptr = (u8 *)&cooked_obj->symbol[0];
92 if (!output_region(fp, offset, ptr, size))
93 {
94 return FALSE;
95 }
96
97 // Section: StrTab
98 n = obj->symbol_name_index;
99 offset = obj->section[n].sh_offset;
100 size = obj->section[n].sh_size;
101 ptr = (u8 *)obj->symbol_name.ptr;
102 if (!output_region(fp, offset, ptr, size))
103 {
104 return FALSE;
105 }
106
107 // Section: Object
108 for (i = 0; i < obj->num_data; i++)
109 {
110 n = obj->data[i].index;
111 offset = obj->section[n].sh_offset;
112 size = obj->section[n].sh_size;
113 ptr = (u8 *)obj->data[i].section.ptr;
114 if (!output_region(fp, offset, ptr, size))
115 {
116 return FALSE;
117 }
118 }
119 return TRUE;
120 }
121
122
123 /*---------------------------------------------------------------------------*
124 Name: output_region
125
126 Description: Outputs the data with memory sorting attached
127
128 Arguments: fp File pointer
129 ptr Data
130 size Memory block size
131 offset Write start offset
132 Returns: TRUE for success; FALSE for failure.
133 *---------------------------------------------------------------------------*/
output_region(FILE * fp,u32 offset,const u8 * ptr,u32 size)134 static BOOL output_region(FILE * fp, u32 offset, const u8 *ptr, u32 size)
135 {
136 static u8 zero[1] = { '\0' };
137
138 while (ftell(fp) < offset)
139 {
140 if (1 != fwrite(zero, sizeof(u8), 1, fp))
141 {
142 return FALSE;
143 }
144 }
145 return 1 == fwrite(ptr, size, 1, fp) ? TRUE : FALSE;
146 }
147