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
19 static void dol2elf(char *inname
, char *outname
)
22 u8 elfheader
[0x400] = {0};
23 u8 segheader
[0x400] = {0};
24 u8 secheader
[0x400] = {0};
25 u8 strings
[0x400] = "\0.strtab";
27 struct section section
[19];
29 u32 n_text
, n_data
, n_total
;
35 in
= fopen(inname
, "rb");
36 fread(dolheader
, 1, sizeof dolheader
, in
);
41 for (i
= 0; i
< 18; i
++) {
42 section
[i
].offset
= be32(dolheader
+ 4*i
);
43 section
[i
].addr
= be32(dolheader
+ 0x48 + 4*i
);
44 section
[i
].size
= be32(dolheader
+ 0x90 + 4*i
);
45 section
[i
].elf_offset
= elf_offset
;
46 elf_offset
+= -(-section
[i
].size
& -0x100);
50 section
[18].offset
= 0;
51 section
[18].addr
= be32(dolheader
+ 0xd8);
52 section
[18].size
= be32(dolheader
+ 0xdc);
53 section
[18].elf_offset
= elf_offset
;
55 entry
= be32(dolheader
+ 0xe0);
58 for (i
= 0; i
< 7; i
++)
59 if (section
[i
].size
) {
60 sprintf(strings
+ str_offset
, ".text.%d", n_text
);
61 section
[i
].str_offset
= str_offset
;
68 if (section
[i
].size
) {
69 sprintf(strings
+ str_offset
, ".data.%d", n_data
);
70 section
[i
].str_offset
= str_offset
;
71 str_offset
+= i
< 16 ? 8 : 9;
75 n_total
= n_text
+ n_data
;
76 if (section
[18].size
) {
77 sprintf(strings
+ str_offset
, ".bss");
78 section
[i
].str_offset
= str_offset
;
83 printf("%d text sections, %d data sections, %d total (includes bss)\n",
84 n_text
, n_data
, n_total
);
85 printf("entry point = %08x\n", entry
);
87 memset(elfheader
, 0, sizeof elfheader
);
96 wbe16(elfheader
+ 0x10, 2);
97 wbe16(elfheader
+ 0x12, 0x14);
98 wbe32(elfheader
+ 0x14, 1);
99 wbe32(elfheader
+ 0x18, entry
);
100 wbe32(elfheader
+ 0x1c, 0x400);
101 wbe32(elfheader
+ 0x20, 0x800);
102 wbe32(elfheader
+ 0x24, 0);
103 wbe16(elfheader
+ 0x28, 0x34);
104 wbe16(elfheader
+ 0x2a, 0x20);
105 wbe16(elfheader
+ 0x2c, n_total
);
106 wbe16(elfheader
+ 0x2e, 0x28);
107 wbe16(elfheader
+ 0x30, n_total
+ 2);
108 wbe16(elfheader
+ 0x32, 1);
111 for (i
= 0; i
< 19; i
++)
112 if (section
[i
].size
) {
114 wbe32(p
+ 0x04, section
[i
].elf_offset
);
115 wbe32(p
+ 0x08, section
[i
].addr
);
116 wbe32(p
+ 0x0c, section
[i
].addr
);
117 wbe32(p
+ 0x10, i
== 18 ? 0 : section
[i
].size
);
118 wbe32(p
+ 0x14, section
[i
].size
);
119 wbe32(p
+ 0x18, i
< 7 ? 5 : 6);
120 wbe32(p
+ 0x1c, 0x20);
124 p
= secheader
+ 0x28;
129 wbe32(p
+ 0x10, 0xc00);
130 wbe32(p
+ 0x14, 0x400);
137 for (i
= 0; i
< 19; i
++)
138 if (section
[i
].size
) {
139 wbe32(p
+ 0x00, section
[i
].str_offset
);
140 wbe32(p
+ 0x04, i
== 18 ? 8 : 1);
141 wbe32(p
+ 0x08, i
< 7 ? 6 : 3);
142 wbe32(p
+ 0x0c, section
[i
].addr
);
143 wbe32(p
+ 0x10, section
[i
].elf_offset
);
144 wbe32(p
+ 0x14, section
[i
].size
);
147 wbe32(p
+ 0x20, 0x20);
152 out
= fopen(outname
, "wb");
153 fwrite(elfheader
, 1, sizeof elfheader
, out
);
154 fwrite(segheader
, 1, sizeof segheader
, out
);
155 fwrite(secheader
, 1, sizeof secheader
, out
);
156 fwrite(strings
, 1, sizeof strings
, out
);
158 for (i
= 0; i
< 19; i
++)
159 if (section
[i
].size
) {
160 p
= malloc(section
[i
].size
);
161 fseek(in
, section
[i
].offset
, SEEK_SET
);
162 fread(p
, 1, section
[i
].size
, in
);
163 fseek(out
, section
[i
].elf_offset
, SEEK_SET
);
164 fwrite(p
, 1, section
[i
].size
, out
);
172 int main(int argc
, char **argv
)
175 fprintf(stderr
, "Usage: %s <dol> <elf>\n", argv
[0]);
179 dol2elf(argv
[1], argv
[2]);