Skip to content

Commit

Permalink
Sort symbols by address, then parentage, then index
Browse files Browse the repository at this point in the history
  • Loading branch information
Rangi42 committed Oct 28, 2023
1 parent 84f3cb4 commit 908aba4
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/link/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "link/output.h"
#include "link/main.h"
Expand Down Expand Up @@ -325,7 +326,7 @@ static void printSymName(char const *name)
}

// Comparator function for `qsort` to sort symbols
// Symbols are ordered by address, or else by original index for a stable sort
// Symbols are ordered by address, then by parentage, or else by original index for a stable sort
static int compareSymbols(void const *a, void const *b)
{
struct SortedSymbol const *sym1 = (struct SortedSymbol const *)a;
Expand All @@ -334,6 +335,19 @@ static int compareSymbols(void const *a, void const *b)
if (sym1->addr != sym2->addr)
return sym1->addr < sym2->addr ? -1 : 1;

char const *sym1_local = strchr(sym1->sym->name, '.');
char const *sym2_local = strchr(sym2->sym->name, '.');

if (!sym1_local != !sym2_local) {
// Sort parent labels before their child local labels
if (!strncmp(sym1->sym->name, sym2->sym->name, strlen(sym1->sym->name)))
return -1;
if (!strncmp(sym2->sym->name, sym1->sym->name, strlen(sym2->sym->name)))
return 1;
// Sort local labels before unrelated global labels
return sym1_local ? -1 : 1;
}

return sym1->idx < sym2->idx ? -1 : sym1->idx > sym2->idx ? 1 : 0;
}

Expand Down

0 comments on commit 908aba4

Please sign in to comment.