Add dol2elf
[svpe-tools.git] / dol2elf.c
blob47fe16d758ccc30fb7ca98e27d2db1594dfb331b
1 // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
2 // Licensed under the terms of the GNU GPL, version 2
3 // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
5 #include <string.h>
6 #include <stdlib.h>
7 #include <stdio.h>
9 typedef unsigned char u8;
10 typedef unsigned short u16;
11 typedef unsigned int u32;
13 static u32 be32(u8 *p)
15 return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
18 static void wbe16(u8 *p, u16 x)
20 p[0] = x >> 8;
21 p[1] = x;
24 static void wbe32(u8 *p, u32 x)
26 wbe16(p, x >> 16);
27 wbe16(p + 2, x);
30 struct section {
31 u32 addr;
32 u32 size;
33 u32 offset;
34 u32 elf_offset;
35 u32 str_offset;
38 static void dol2elf(char *inname, char *outname)
40 u8 dolheader[0x100];
41 u8 elfheader[0x400] = {0};
42 u8 segheader[0x400] = {0};
43 u8 secheader[0x400] = {0};
44 u8 strings[0x400] = "\0.strtab";
45 u32 str_offset = 9;
46 struct section section[19];
47 FILE *in, *out;
48 u32 n_text, n_data, n_total;
49 u32 entry;
50 u32 elf_offset;
51 u32 i;
52 u8 *p;
54 in = fopen(inname, "rb");
55 fread(dolheader, 1, sizeof dolheader, in);
57 elf_offset = 0x1000;
59 // 7 text, 11 data
60 for (i = 0; i < 18; i++) {
61 section[i].offset = be32(dolheader + 4*i);
62 section[i].addr = be32(dolheader + 0x48 + 4*i);
63 section[i].size = be32(dolheader + 0x90 + 4*i);
64 section[i].elf_offset = elf_offset;
65 elf_offset += -(-section[i].size & -0x100);
68 // bss
69 section[18].offset = 0;
70 section[18].addr = be32(dolheader + 0xd8);
71 section[18].size = be32(dolheader + 0xdc);
72 section[18].elf_offset = elf_offset;
74 entry = be32(dolheader + 0xe0);
76 n_text = 0;
77 for (i = 0; i < 7; i++)
78 if (section[i].size) {
79 sprintf(strings + str_offset, ".text.%d", n_text);
80 section[i].str_offset = str_offset;
81 str_offset += 8;
82 n_text++;
85 n_data = 0;
86 for ( ; i < 18; i++)
87 if (section[i].size) {
88 sprintf(strings + str_offset, ".data.%d", n_data);
89 section[i].str_offset = str_offset;
90 str_offset += i < 16 ? 8 : 9;
91 n_data++;
94 n_total = n_text + n_data;
95 if (section[18].size) {
96 sprintf(strings + str_offset, ".bss");
97 section[i].str_offset = str_offset;
98 str_offset += 5;
99 n_total++;
102 printf("%d text sections, %d data sections, %d total (includes bss)\n",
103 n_text, n_data, n_total);
104 printf("entry point = %08x\n", entry);
106 memset(elfheader, 0, sizeof elfheader);
107 elfheader[0] = 0x7f;
108 elfheader[1] = 0x45;
109 elfheader[2] = 0x4c;
110 elfheader[3] = 0x46;
111 elfheader[4] = 0x01;
112 elfheader[5] = 0x02;
113 elfheader[6] = 0x01;
115 wbe16(elfheader + 0x10, 2);
116 wbe16(elfheader + 0x12, 0x14);
117 wbe32(elfheader + 0x14, 1);
118 wbe32(elfheader + 0x18, entry);
119 wbe32(elfheader + 0x1c, 0x400);
120 wbe32(elfheader + 0x20, 0x800);
121 wbe32(elfheader + 0x24, 0);
122 wbe16(elfheader + 0x28, 0x34);
123 wbe16(elfheader + 0x2a, 0x20);
124 wbe16(elfheader + 0x2c, n_total);
125 wbe16(elfheader + 0x2e, 0x28);
126 wbe16(elfheader + 0x30, n_total + 2);
127 wbe16(elfheader + 0x32, 1);
129 p = segheader;
130 for (i = 0; i < 19; i++)
131 if (section[i].size) {
132 wbe32(p + 0x00, 1);
133 wbe32(p + 0x04, section[i].elf_offset);
134 wbe32(p + 0x08, section[i].addr);
135 wbe32(p + 0x0c, section[i].addr);
136 wbe32(p + 0x10, i == 18 ? 0 : section[i].size);
137 wbe32(p + 0x14, section[i].size);
138 wbe32(p + 0x18, i < 7 ? 5 : 6);
139 wbe32(p + 0x1c, 0x20);
140 p += 0x20;
143 p = secheader + 0x28;
144 wbe32(p + 0x00, 1);
145 wbe32(p + 0x04, 3);
146 wbe32(p + 0x08, 0);
147 wbe32(p + 0x0c, 0);
148 wbe32(p + 0x10, 0xc00);
149 wbe32(p + 0x14, 0x400);
150 wbe32(p + 0x18, 0);
151 wbe32(p + 0x1c, 0);
152 wbe32(p + 0x20, 1);
153 wbe32(p + 0x24, 0);
154 p += 0x28;
156 for (i = 0; i < 19; i++)
157 if (section[i].size) {
158 wbe32(p + 0x00, section[i].str_offset);
159 wbe32(p + 0x04, i == 18 ? 8 : 1);
160 wbe32(p + 0x08, i < 7 ? 6 : 3);
161 wbe32(p + 0x0c, section[i].addr);
162 wbe32(p + 0x10, section[i].elf_offset);
163 wbe32(p + 0x14, section[i].size);
164 wbe32(p + 0x18, 0);
165 wbe32(p + 0x1c, 0);
166 wbe32(p + 0x20, 0x20);
167 wbe32(p + 0x24, 0);
168 p += 0x28;
171 out = fopen(outname, "wb");
172 fwrite(elfheader, 1, sizeof elfheader, out);
173 fwrite(segheader, 1, sizeof segheader, out);
174 fwrite(secheader, 1, sizeof secheader, out);
175 fwrite(strings, 1, sizeof strings, out);
177 for (i = 0; i < 19; i++)
178 if (section[i].size) {
179 p = malloc(section[i].size);
180 fseek(in, section[i].offset, SEEK_SET);
181 fread(p, 1, section[i].size, in);
182 fseek(out, section[i].elf_offset, SEEK_SET);
183 fwrite(p, 1, section[i].size, out);
184 free(p);
187 fclose(out);
188 fclose(in);
191 int main(int argc, char **argv)
193 if (argc != 3) {
194 fprintf(stderr, "Usage: %s <dol> <elf>\n", argv[0]);
195 exit(1);
198 dol2elf(argv[1], argv[2]);
200 return 0;