1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - bin2obj
3 File: object.c
4
5 Copyright 2005-2008, 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 void header_init(ELF32_ElfHeader * h, u16 machine, u8 endian);
20 /*---------------------------------------------------------------------------*
21 Name: object_init
22
23 Description: Initializes object information.
24
25 Arguments: obj Object
26
27 Returns: TRUE for success; FALSE for failure.
28 *---------------------------------------------------------------------------*/
object_init(Object * obj,u16 machine,u8 endian)29 void object_init(Object * obj, u16 machine, u8 endian)
30 {
31 ELF32_SectionHeader *s;
32 ELF32_ElfHeader *h;
33
34 //-----------------------------------------------------------------------
35 // Initialize area ZERO
36 //-----------------------------------------------------------------------
37 memset(obj, 0, sizeof(Object));
38
39 //-----------------------------------------------------------------------
40 // Initialization of Elf Header
41 //-----------------------------------------------------------------------
42 h = &obj->header;
43 header_init(h, machine, endian);
44
45 //-----------------------------------------------------------------------
46 // Register default section
47 //-----------------------------------------------------------------------
48
49 // The section with index=0 is dummy=NULL
50 (void)add_section(obj, NULL, SHT_NULL, 0, 0, 0);
51
52 // index=1 section name table
53 h->e_shstrndx = add_section(obj, ".shstrtab", SHT_STRTAB, SHF_NULL, obj->section_name.size, 0);
54
55 // index=2 symbol info structure
56 obj->symbol_index = add_section(obj, ".symtab", SHT_SYMTAB, SHF_NULL, 0, 4);
57
58 // index=3 symbol name table
59 obj->symbol_name_index =
60 add_section(obj, ".strtab", SHT_STRTAB, SHF_NULL, obj->symbol_name.size, 1);
61
62 // Add symbol information setting
63 s = &obj->section[obj->symbol_index];
64 s->sh_link = obj->symbol_name_index; // symbol name table link
65 s->sh_info = -1; // Initialization of symbol's last index value
66 s->sh_entsize = sizeof(ELF32_Symbol); // symbol entry size
67
68 //-----------------------------------------------------------------------
69 // Symbol table initialization
70 //-----------------------------------------------------------------------
71
72 // Register index=0 NULL symbol
73 (void)add_symbol(obj, NULL, 0, 0, 0);
74 }
75
76 /*---------------------------------------------------------------------------*
77 Name: header_init
78
79 Description: Creates ELF header info.
80
81 Arguments: elfHeader ELF header info
82 machine Machine code
83 EM_ARM // ARM
84 EM_PPC // PPC
85 endian ELF's endian
86 ELFDATA2LSB // Little Endian
87 ELFDATA2MSB // Big Endian
88 Returns: None.
89 *---------------------------------------------------------------------------*/
header_init(ELF32_ElfHeader * h,u16 machine,u8 endian)90 static void header_init(ELF32_ElfHeader * h, u16 machine, u8 endian)
91 {
92 memset(h, 0, sizeof(ELF32_ElfHeader));
93 h->e_ident[0] = ELFMAG0; // 0x7f
94 h->e_ident[1] = ELFMAG1; // 'E'
95 h->e_ident[2] = ELFMAG2; // 'L'
96 h->e_ident[3] = ELFMAG3; // 'F'
97 h->e_ident[4] = ELFCLASS32; // 32 bit
98 h->e_ident[5] = endian; // ELFDATA2MSB/ELFDATA2LSB
99 h->e_ident[6] = EV_CURRENT; // CURRENT
100 h->e_type = ET_REL;
101 h->e_machine = machine;
102 h->e_version = EV_CURRENT;
103 h->e_entry = 0;
104 h->e_phoff = 0;
105 h->e_shoff = 0; // Fill in with correct values later
106 h->e_flags = 0;
107 h->e_ehsize = sizeof(ELF32_ElfHeader);
108 h->e_phentsize = 0;
109 h->e_phnum = 0;
110 h->e_shentsize = sizeof(ELF32_SectionHeader);
111 h->e_shnum = 0; // +1 each time section increases
112 h->e_shstrndx = 0; // Fill in with correct values later
113
114 return;
115 }
116
117 /*---------------------------------------------------------------------------*
118 Name: map_section
119
120 Description: Writes the section's location information.
121
122 Arguments: obj Object
123
124 Returns: None.
125 *---------------------------------------------------------------------------*/
map_section(Object * obj)126 void map_section(Object * obj)
127 {
128 ELF32_ElfHeader *h;
129 ELF32_SectionHeader *s;
130 u32 offset;
131 int i;
132
133 // ELF HEADER/SECTION HEADER position calculation
134 h = &obj->header;
135 offset = h->e_ehsize;
136 h->e_shoff = roundup(offset, 4);
137 offset = h->e_shoff + h->e_shentsize * h->e_shnum;
138
139 // Section's position calculation
140 for (i = 1; i < obj->header.e_shnum; i++)
141 {
142 s = &obj->section[i];
143 s->sh_offset = roundup(offset, s->sh_addralign);
144 offset = s->sh_offset + s->sh_size;
145 }
146 return;
147 }
148
149 /*---------------------------------------------------------------------------*
150 Name: roundup
151
152 Description: Rounds up integers.
153
154 Arguments: val Value
155 align Boundary value
156
157 Returns: Result
158 *---------------------------------------------------------------------------*/
roundup(u32 val,u32 align)159 u32 roundup(u32 val, u32 align)
160 {
161 if (align > 1)
162 {
163 u32 n = val % align;
164
165 if (n > 0)
166 {
167 val += (align - n);
168 }
169 }
170 return val;
171 }
172
173
174 /*---------------------------------------------------------------------------*
175 Name: conv_to_big_endian
176
177 Description: Convert to big endian
178
179 Arguments: src before conversion
180 dest after conversion
181
182 Returns: Result
183 *---------------------------------------------------------------------------*/
Be32(u32 x)184 static u32 Be32(u32 x)
185 {
186 return (u32)(((x) >> 24) & 0x000000ff) | (((x) >> 8) & 0x0000ff00) |
187 (((x) << 8) & 0x00ff0000) | (((x) << 24) & 0xff000000);
188 }
189
Be16(u16 x)190 static u16 Be16(u16 x)
191 {
192 return (u16)(((x) >> 8) & 0x00ff) | (((x) << 8) & 0xff00);
193 }
194
conv_to_big_endian_header(const ELF32_ElfHeader * src,ELF32_ElfHeader * dest)195 static void conv_to_big_endian_header(const ELF32_ElfHeader * src, ELF32_ElfHeader * dest)
196 {
197 memcpy(dest->e_ident, src->e_ident, EI_NIDENT);
198 dest->e_type = Be16(src->e_type);
199 dest->e_machine = Be16(src->e_machine);
200 dest->e_version = Be32(src->e_version);
201 dest->e_entry = Be32(src->e_entry);
202 dest->e_phoff = Be32(src->e_phoff);
203 dest->e_shoff = Be32(src->e_shoff);
204 dest->e_flags = Be32(src->e_flags);
205 dest->e_ehsize = Be16(src->e_ehsize);
206 dest->e_phentsize = Be16(src->e_phentsize);
207 dest->e_phnum = Be16(src->e_phnum);
208 dest->e_shentsize = Be16(src->e_shentsize);
209 dest->e_shnum = Be16(src->e_shnum);
210 dest->e_shstrndx = Be16(src->e_shstrndx);
211 }
212
conv_to_big_endian_section(const ELF32_SectionHeader * src,ELF32_SectionHeader * dest)213 static void conv_to_big_endian_section(const ELF32_SectionHeader * src, ELF32_SectionHeader * dest)
214 {
215 dest->sh_name = Be32(src->sh_name);
216 dest->sh_type = Be32(src->sh_type);
217 dest->sh_flags = Be32(src->sh_flags);
218 dest->sh_addr = Be32(src->sh_addr);
219 dest->sh_offset = Be32(src->sh_offset);
220 dest->sh_size = Be32(src->sh_size);
221 dest->sh_link = Be32(src->sh_link);
222 dest->sh_info = Be32(src->sh_info);
223 dest->sh_addralign = Be32(src->sh_addralign);
224 dest->sh_entsize = Be32(src->sh_entsize);
225 }
226
conv_to_big_endian_symbol(const ELF32_Symbol * src,ELF32_Symbol * dest)227 static void conv_to_big_endian_symbol(const ELF32_Symbol * src, ELF32_Symbol * dest)
228 {
229 dest->st_name = Be32(src->st_name);
230 dest->st_value = Be32(src->st_value);
231 dest->st_size = Be32(src->st_size);
232 dest->st_info = src->st_info;
233 dest->st_other = src->st_other;
234 dest->st_shndx = Be16(src->st_shndx);
235 }
236
conv_to_big_endian(const Object * src,Object * dest)237 void conv_to_big_endian(const Object * src, Object * dest)
238 {
239 int i, n;
240
241 conv_to_big_endian_header(&src->header, &dest->header);
242
243 for (i = 0; i < src->header.e_shnum; i++)
244 {
245 conv_to_big_endian_section(&src->section[i], &dest->section[i]);
246 }
247
248 n = src->section[src->symbol_index].sh_size / sizeof(src->symbol[0]);
249 for (i = 0; i < n; i++)
250 {
251 conv_to_big_endian_symbol(&src->symbol[i], &dest->symbol[i]);
252 }
253 }
254