diff options
Diffstat (limited to 'utils/imxtools/sbtools/elf.c')
-rw-r--r-- | utils/imxtools/sbtools/elf.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/utils/imxtools/sbtools/elf.c b/utils/imxtools/sbtools/elf.c index 35bc1605d3..c41fc27fdd 100644 --- a/utils/imxtools/sbtools/elf.c +++ b/utils/imxtools/sbtools/elf.c | |||
@@ -229,7 +229,7 @@ static int elf_simplify_compare(const void *a, const void *b) | |||
229 | 229 | ||
230 | void elf_simplify(struct elf_params_t *params) | 230 | void elf_simplify(struct elf_params_t *params) |
231 | { | 231 | { |
232 | /** find all sections of the same times which are contiguous and merge them */ | 232 | /** find all sections of the same types which are contiguous and merge them */ |
233 | 233 | ||
234 | /* count sections */ | 234 | /* count sections */ |
235 | int nr_sections = 0; | 235 | int nr_sections = 0; |
@@ -312,6 +312,61 @@ void elf_simplify(struct elf_params_t *params) | |||
312 | free(sections); | 312 | free(sections); |
313 | } | 313 | } |
314 | 314 | ||
315 | /* sort by increasing address */ | ||
316 | static int elf_addr_compare(const void *a, const void *b) | ||
317 | { | ||
318 | const struct elf_section_t *sa = a; | ||
319 | const struct elf_section_t *sb = b; | ||
320 | return sa->addr - sb->addr; | ||
321 | } | ||
322 | |||
323 | void elf_sort_by_address(struct elf_params_t *params) | ||
324 | { | ||
325 | /** sort sections by address */ | ||
326 | |||
327 | /* count sections */ | ||
328 | int nr_sections = 0; | ||
329 | struct elf_section_t *cur_sec = params->first_section; | ||
330 | while(cur_sec) | ||
331 | { | ||
332 | nr_sections++; | ||
333 | cur_sec = cur_sec->next; | ||
334 | } | ||
335 | |||
336 | /* put all sections in an array and free list */ | ||
337 | struct elf_section_t *sections = malloc(sizeof(struct elf_section_t) * nr_sections); | ||
338 | cur_sec = params->first_section; | ||
339 | for(int i = 0; i < nr_sections; i++) | ||
340 | { | ||
341 | memcpy(§ions[i], cur_sec, sizeof(struct elf_section_t)); | ||
342 | struct elf_section_t *old = cur_sec; | ||
343 | cur_sec = cur_sec->next; | ||
344 | free(old); | ||
345 | } | ||
346 | |||
347 | /* sort them by type and increasing addresses */ | ||
348 | qsort(sections, nr_sections, sizeof(struct elf_section_t), &elf_addr_compare); | ||
349 | |||
350 | /* put back on a list and free array */ | ||
351 | struct elf_section_t **prev_ptr = ¶ms->first_section; | ||
352 | struct elf_section_t *prev_sec = NULL; | ||
353 | for(int i = 0; i < nr_sections; i++) | ||
354 | { | ||
355 | /* skip empty sections produced by simplification */ | ||
356 | if(sections[i].size == 0) | ||
357 | continue; | ||
358 | |||
359 | struct elf_section_t *sec = malloc(sizeof(struct elf_section_t)); | ||
360 | memcpy(sec, §ions[i], sizeof(struct elf_section_t)); | ||
361 | *prev_ptr = sec; | ||
362 | prev_ptr = &sec->next; | ||
363 | prev_sec = sec; | ||
364 | } | ||
365 | *prev_ptr = NULL; | ||
366 | params->last_section = prev_sec; | ||
367 | free(sections); | ||
368 | } | ||
369 | |||
315 | void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, | 370 | void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, |
316 | elf_printf_fn_t printf, void *user) | 371 | elf_printf_fn_t printf, void *user) |
317 | { | 372 | { |