summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2012-12-16 21:06:38 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2012-12-16 21:28:41 +0100
commitf4f600fc52d38e4a287913050880647144d1873c (patch)
tree8f7d94f20d32f0cbdd97c8375e7bd98e41a69500 /utils
parentbe9787f2e62ed7eb741bee635e3d4dc26bc2d426 (diff)
downloadrockbox-f4f600fc52d38e4a287913050880647144d1873c.tar.gz
rockbox-f4f600fc52d38e4a287913050880647144d1873c.tar.bz2
rockbox-f4f600fc52d38e4a287913050880647144d1873c.zip
imxtools/sbtools: add elf function (sort by address)
Change-Id: Ib68746e11b43eadbbe0443626d4dc65d998348fa
Diffstat (limited to 'utils')
-rw-r--r--utils/imxtools/sbtools/elf.c57
-rw-r--r--utils/imxtools/sbtools/elf.h1
2 files changed, 57 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)
void elf_simplify(struct elf_params_t *params)
{
- /** find all sections of the same times which are contiguous and merge them */
+ /** find all sections of the same types which are contiguous and merge them */
/* count sections */
int nr_sections = 0;
@@ -312,6 +312,61 @@ void elf_simplify(struct elf_params_t *params)
free(sections);
}
+/* sort by increasing address */
+static int elf_addr_compare(const void *a, const void *b)
+{
+ const struct elf_section_t *sa = a;
+ const struct elf_section_t *sb = b;
+ return sa->addr - sb->addr;
+}
+
+void elf_sort_by_address(struct elf_params_t *params)
+{
+ /** sort sections by address */
+
+ /* count sections */
+ int nr_sections = 0;
+ struct elf_section_t *cur_sec = params->first_section;
+ while(cur_sec)
+ {
+ nr_sections++;
+ cur_sec = cur_sec->next;
+ }
+
+ /* put all sections in an array and free list */
+ struct elf_section_t *sections = malloc(sizeof(struct elf_section_t) * nr_sections);
+ cur_sec = params->first_section;
+ for(int i = 0; i < nr_sections; i++)
+ {
+ memcpy(&sections[i], cur_sec, sizeof(struct elf_section_t));
+ struct elf_section_t *old = cur_sec;
+ cur_sec = cur_sec->next;
+ free(old);
+ }
+
+ /* sort them by type and increasing addresses */
+ qsort(sections, nr_sections, sizeof(struct elf_section_t), &elf_addr_compare);
+
+ /* put back on a list and free array */
+ struct elf_section_t **prev_ptr = &params->first_section;
+ struct elf_section_t *prev_sec = NULL;
+ for(int i = 0; i < nr_sections; i++)
+ {
+ /* skip empty sections produced by simplification */
+ if(sections[i].size == 0)
+ continue;
+
+ struct elf_section_t *sec = malloc(sizeof(struct elf_section_t));
+ memcpy(sec, &sections[i], sizeof(struct elf_section_t));
+ *prev_ptr = sec;
+ prev_ptr = &sec->next;
+ prev_sec = sec;
+ }
+ *prev_ptr = NULL;
+ params->last_section = prev_sec;
+ free(sections);
+}
+
void elf_write_file(struct elf_params_t *params, elf_write_fn_t write,
elf_printf_fn_t printf, void *user)
{
diff --git a/utils/imxtools/sbtools/elf.h b/utils/imxtools/sbtools/elf.h
index ae4e3b4225..2e14e66fd3 100644
--- a/utils/imxtools/sbtools/elf.h
+++ b/utils/imxtools/sbtools/elf.h
@@ -83,6 +83,7 @@ void elf_add_fill_section(struct elf_params_t *params,
uint32_t elf_translate_virtual_address(struct elf_params_t *params, uint32_t addr);
void elf_translate_addresses(struct elf_params_t *params);
void elf_simplify(struct elf_params_t *params);
+void elf_sort_by_address(struct elf_params_t *params);
void elf_write_file(struct elf_params_t *params, elf_write_fn_t write, elf_printf_fn_t printf, void *user);
bool elf_read_file(struct elf_params_t *params, elf_read_fn_t read, elf_printf_fn_t printf,
void *user);