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
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
)
24 static void wbe32(u8
*p
, u32 x
)
38 static void dol2elf(char *inname
, char *outname
)
41 u8 elfheader
[0x400] = {0};
42 u8 segheader
[0x400] = {0};
43 u8 secheader
[0x400] = {0};
44 u8 strings
[0x400] = "\0.strtab";
46 struct section section
[19];
48 u32 n_text
, n_data
, n_total
;
54 in
= fopen(inname
, "rb");
55 fread(dolheader
, 1, sizeof dolheader
, in
);
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);
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);
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
;
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;
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
;
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
);
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);
130 for (i
= 0; i
< 19; i
++)
131 if (section
[i
].size
) {
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);
143 p
= secheader
+ 0x28;
148 wbe32(p
+ 0x10, 0xc00);
149 wbe32(p
+ 0x14, 0x400);
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
);
166 wbe32(p
+ 0x20, 0x20);
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
);
191 int main(int argc
, char **argv
)
194 fprintf(stderr
, "Usage: %s <dol> <elf>\n", argv
[0]);
198 dol2elf(argv
[1], argv
[2]);