summaryrefslogtreecommitdiff
path: root/utils/imxtools/sbtools
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-11-28 00:06:31 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-11-28 00:06:31 +0100
commit1c140410412ffc88d528689658410b2c97e9d677 (patch)
treeb055905f9957258d67143eeda3031c02b3356cbe /utils/imxtools/sbtools
parent8189732e52080353dbf38933a8c71c6dc6811f2a (diff)
downloadrockbox-1c140410412ffc88d528689658410b2c97e9d677.tar.gz
rockbox-1c140410412ffc88d528689658410b2c97e9d677.zip
sbtoelf: implement elf simplification
Change-Id: Icfac5a2aa6a7b3582054321df003c6bb217b59d0
Diffstat (limited to 'utils/imxtools/sbtools')
-rw-r--r--utils/imxtools/sbtools/elf.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/utils/imxtools/sbtools/elf.c b/utils/imxtools/sbtools/elf.c
index 53adcd1160..35bc1605d3 100644
--- a/utils/imxtools/sbtools/elf.c
+++ b/utils/imxtools/sbtools/elf.c
@@ -217,9 +217,99 @@ void elf_add_fill_section(struct elf_params_t *params,
217 sec->pattern = pattern; 217 sec->pattern = pattern;
218} 218}
219 219
220/* sort by increasing type and then increasing address */
221static int elf_simplify_compare(const void *a, const void *b)
222{
223 const struct elf_section_t *sa = a;
224 const struct elf_section_t *sb = b;
225 if(sa->type != sb->type)
226 return sa->type - sb->type;
227 return sa->addr - sb->addr;
228}
229
220void elf_simplify(struct elf_params_t *params) 230void elf_simplify(struct elf_params_t *params)
221{ 231{
232 /** find all sections of the same times which are contiguous and merge them */
233
234 /* count sections */
235 int nr_sections = 0;
236 struct elf_section_t *cur_sec = params->first_section;
237 while(cur_sec)
238 {
239 nr_sections++;
240 cur_sec = cur_sec->next;
241 }
222 242
243 /* put all sections in an array and free list */
244 struct elf_section_t *sections = malloc(sizeof(struct elf_section_t) * nr_sections);
245 cur_sec = params->first_section;
246 for(int i = 0; i < nr_sections; i++)
247 {
248 memcpy(&sections[i], cur_sec, sizeof(struct elf_section_t));
249 struct elf_section_t *old = cur_sec;
250 cur_sec = cur_sec->next;
251 free(old);
252 }
253
254 /* sort them by type and increasing addresses */
255 qsort(sections, nr_sections, sizeof(struct elf_section_t), &elf_simplify_compare);
256
257 /* merge them ! */
258 cur_sec = &sections[0];
259 for(int i = 1; i < nr_sections; i++)
260 {
261 /* different type => no */
262 if(sections[i].type != cur_sec->type)
263 goto Lnext;
264 /* (for fill) different pattern => no */
265 if(sections[i].type == EST_FILL && sections[i].pattern != cur_sec->pattern)
266 goto Lnext;
267 /* not contiguous => no */
268 if(sections[i].addr != cur_sec->addr + cur_sec->size)
269 goto Lnext;
270 /* merge !! */
271 if(sections[i].type == EST_FILL)
272 {
273 cur_sec->size += sections[i].size;
274 sections[i].size = 0; // will be ignored by rebuilding (see below)
275 }
276 else if(sections[i].type == EST_LOAD)
277 {
278 // merge data also
279 void *data = malloc(cur_sec->size + sections[i].size);
280 memcpy(data, cur_sec->section, cur_sec->size);
281 memcpy(data + cur_sec->size, sections[i].section, sections[i].size);
282 free(cur_sec->section);
283 free(sections[i].section);
284 cur_sec->section = data;
285 cur_sec->size += sections[i].size;
286 sections[i].size = 0; // will be ignored by rebuilding (see below)
287 }
288 continue;
289
290 /* update current section to consider */
291 Lnext:
292 cur_sec = &sections[i];
293 }
294
295 /* put back on a list and free array */
296 struct elf_section_t **prev_ptr = &params->first_section;
297 struct elf_section_t *prev_sec = NULL;
298 for(int i = 0; i < nr_sections; i++)
299 {
300 /* skip empty sections produced by simplification */
301 if(sections[i].size == 0)
302 continue;
303
304 struct elf_section_t *sec = malloc(sizeof(struct elf_section_t));
305 memcpy(sec, &sections[i], sizeof(struct elf_section_t));
306 *prev_ptr = sec;
307 prev_ptr = &sec->next;
308 prev_sec = sec;
309 }
310 *prev_ptr = NULL;
311 params->last_section = prev_sec;
312 free(sections);
223} 313}
224 314
225void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, 315void elf_write_file(struct elf_params_t *params, elf_write_fn_t write,