#include <ctype.h>
#include <limits.h>
-#ifndef ARRAY_SIZE
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
-#endif
#define KSYM_NAME_LEN 128
exit(1);
}
-/*
- * This ignores the intensely annoying "mapping symbols" found
- * in ARM ELF files: $a, $t and $d.
- */
-static int is_arm_mapping_symbol(const char *str)
+static char *sym_name(const struct sym_entry *s)
{
- return str[0] == '$' && strchr("axtd", str[1])
- && (str[2] == '\0' || str[2] == '.');
+ return (char *)s->sym + 1;
}
static int check_symbol_range(const char *sym, unsigned long long addr,
return -1;
}
- else if (toupper(stype) == 'U' ||
- is_arm_mapping_symbol(sym))
+ else if (toupper(stype) == 'U')
return -1;
- /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */
+ /*
+ * Ignore generated symbols such as:
+ * - mapping symbols in ARM ELF files ($a, $t, and $d)
+ * - MIPS ELF local symbols ($L123 instead of .L123)
+ */
else if (sym[0] == '$')
return -1;
/* exclude debugging symbols */
"unable to allocate required amount of memory\n");
exit(EXIT_FAILURE);
}
- strcpy((char *)s->sym + 1, sym);
+ strcpy(sym_name(s), sym);
s->sym[0] = stype;
s->percpu_absolute = 0;
NULL };
int i;
- char *sym_name = (char *)s->sym + 1;
+ const char *name = sym_name(s);
/* if --all-symbols is not specified, then symbols outside the text
* and inittext sections are discarded */
* rules.
*/
if ((s->addr == text_range_text->end &&
- strcmp(sym_name,
- text_range_text->end_sym)) ||
+ strcmp(name, text_range_text->end_sym)) ||
(s->addr == text_range_inittext->end &&
- strcmp(sym_name,
- text_range_inittext->end_sym)))
+ strcmp(name, text_range_inittext->end_sym)))
return 0;
}
/* Exclude symbols which vary between passes. */
for (i = 0; special_symbols[i]; i++)
- if (strcmp(sym_name, special_symbols[i]) == 0)
+ if (strcmp(name, special_symbols[i]) == 0)
return 0;
for (i = 0; special_prefixes[i]; i++) {
int l = strlen(special_prefixes[i]);
- if (l <= strlen(sym_name) &&
- strncmp(sym_name, special_prefixes[i], l) == 0)
+ if (strncmp(name, special_prefixes[i], l) == 0)
return 0;
}
for (i = 0; special_suffixes[i]; i++) {
- int l = strlen(sym_name) - strlen(special_suffixes[i]);
+ int l = strlen(name) - strlen(special_suffixes[i]);
- if (l >= 0 && strcmp(sym_name + l, special_suffixes[i]) == 0)
+ if (l >= 0 && strcmp(name + l, special_suffixes[i]) == 0)
return 0;
}
return 1;
}
+/* remove all the invalid symbols from the table */
+static void shrink_table(void)
+{
+ unsigned int i, pos;
+
+ pos = 0;
+ for (i = 0; i < table_cnt; i++) {
+ if (symbol_valid(&table[i])) {
+ if (pos != i)
+ table[pos] = table[i];
+ pos++;
+ } else {
+ free(table[i].sym);
+ }
+ }
+ table_cnt = pos;
+
+ /* When valid symbol is not registered, exit to error */
+ if (!table_cnt) {
+ fprintf(stderr, "No valid symbol.\n");
+ exit(1);
+ }
+}
+
static void read_map(FILE *in)
{
while (!feof(in)) {
token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--;
}
-/* remove all the invalid symbols from the table and do the initial token count */
+/* do the initial token count */
static void build_initial_tok_table(void)
{
- unsigned int i, pos;
+ unsigned int i;
- pos = 0;
- for (i = 0; i < table_cnt; i++) {
- if ( symbol_valid(&table[i]) ) {
- if (pos != i)
- table[pos] = table[i];
- learn_symbol(table[pos].sym, table[pos].len);
- pos++;
- }
- }
- table_cnt = pos;
+ for (i = 0; i < table_cnt; i++)
+ learn_symbol(table[i].sym, table[i].len);
}
static void *find_token(unsigned char *str, int len, unsigned char *token)
insert_real_symbols_in_table();
- /* When valid symbol is not registered, exit to error */
- if (!table_cnt) {
- fprintf(stderr, "No valid symbol.\n");
- exit(1);
- }
-
optimize_result();
}
/* guess for "linker script provide" symbol */
static int may_be_linker_script_provide_symbol(const struct sym_entry *se)
{
- const char *symbol = (char *)se->sym + 1;
+ const char *symbol = sym_name(se);
int len = se->len - 1;
if (len < 8)
return wa - wb;
/* sort by the number of prefix underscores */
- wa = prefix_underscores_count((const char *)sa->sym + 1);
- wb = prefix_underscores_count((const char *)sb->sym + 1);
+ wa = prefix_underscores_count(sym_name(sa));
+ wb = prefix_underscores_count(sym_name(sb));
if (wa != wb)
return wa - wb;
{
unsigned int i;
- relative_base = -1ULL;
for (i = 0; i < table_cnt; i++)
- if (!symbol_absolute(&table[i]) &&
- table[i].addr < relative_base)
+ if (!symbol_absolute(&table[i])) {
+ /*
+ * The table is sorted by address.
+ * Take the first non-absolute symbol value.
+ */
relative_base = table[i].addr;
+ return;
+ }
}
int main(int argc, char **argv)
usage();
read_map(stdin);
+ shrink_table();
if (absolute_percpu)
make_percpus_absolute();
+ sort_symbols();
if (base_relative)
record_relative_base();
- sort_symbols();
optimize_token_table();
write_src();