Re: ARM undefined symbols. Again.

From: Paulo Marques
Date: Fri Feb 25 2005 - 15:58:19 EST


Linus Torvalds wrote:
[...]
That makes no sense. Or, more likely, it means that the toolchain people are incompetent bastards who don't care about bugs and have no pride at all in what they do.

Errmm... I really feel pretty small coming in on a Russell King / Linus Torvalds discussion, but I was the one who promised the patch and I just wanted to keep my promises.

The patch (against 2.6.11-rc5) is attached, should you decide to use it.

IMHO it makes the kallsyms code look nicer, by getting rid of the __attribute__((weak)) statements int kernel/kallsyms.c code.

Me getting out of here now....

--
Paulo Marques - www.grupopie.com

All that is necessary for the triumph of evil is that good men do nothing.
Edmund Burke (1729 - 1797)
diff -uprN -X dontdiff linux-2.6.11-rc5-vanilla/kernel/kallsyms.c linux-2.6.11-rc5/kernel/kallsyms.c
--- linux-2.6.11-rc5-vanilla/kernel/kallsyms.c 2005-02-25 20:36:44.000000000 +0000
+++ linux-2.6.11-rc5/kernel/kallsyms.c 2005-02-25 20:15:19.000000000 +0000
@@ -29,14 +29,14 @@
#endif

/* These will be re-linked against their real values during the second link stage */
-extern unsigned long kallsyms_addresses[] __attribute__((weak));
-extern unsigned long kallsyms_num_syms __attribute__((weak,section("data")));
-extern u8 kallsyms_names[] __attribute__((weak));
+extern unsigned long kallsyms_addresses[];
+extern unsigned long kallsyms_num_syms;
+extern u8 kallsyms_names[];

-extern u8 kallsyms_token_table[] __attribute__((weak));
-extern u16 kallsyms_token_index[] __attribute__((weak));
+extern u8 kallsyms_token_table[];
+extern u16 kallsyms_token_index[];

-extern unsigned long kallsyms_markers[] __attribute__((weak));
+extern unsigned long kallsyms_markers[];

static inline int is_kernel_inittext(unsigned long addr)
{
diff -uprN -X dontdiff linux-2.6.11-rc5-vanilla/Makefile linux-2.6.11-rc5/Makefile
--- linux-2.6.11-rc5-vanilla/Makefile 2005-02-25 20:36:15.000000000 +0000
+++ linux-2.6.11-rc5/Makefile 2005-02-25 20:25:44.000000000 +0000
@@ -702,14 +702,20 @@ quiet_cmd_kallsyms = KSYM $@
cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
$(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@

-.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
+quiet_cmd_kallsyms0 = KSYM $@
+ cmd_kallsyms0 = $(KALLSYMS) -0 > $@
+
+.tmp_kallsyms0.o .tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
$(call if_changed_dep,as_o_S)

+.tmp_kallsyms0.S: $(KALLSYMS) FORCE
+ $(call cmd,kallsyms0)
+
.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
$(call cmd,kallsyms)

# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
-.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
+.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms0.o FORCE
$(call if_changed_rule,ksym_ld)

.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
diff -uprN -X dontdiff linux-2.6.11-rc5-vanilla/scripts/kallsyms.c linux-2.6.11-rc5/scripts/kallsyms.c
--- linux-2.6.11-rc5-vanilla/scripts/kallsyms.c 2005-02-25 20:36:45.000000000 +0000
+++ linux-2.6.11-rc5/scripts/kallsyms.c 2005-02-25 20:33:25.000000000 +0000
@@ -93,7 +93,7 @@ unsigned char best_table_len[256];
static void
usage(void)
{
- fprintf(stderr, "Usage: kallsyms [--all-symbols] < in.map > out.S\n");
+ fprintf(stderr, "Usage: kallsyms [--all-symbols] [-0] < in.map > out.S\n");
exit(1);
}

@@ -230,6 +230,20 @@ static void output_label(char *label)
printf("%s:\n",label);
}

+static void output_header(void)
+{
+ printf("#include <asm/types.h>\n");
+ printf("#if BITS_PER_LONG == 64\n");
+ printf("#define PTR .quad\n");
+ printf("#define ALGN .align 8\n");
+ printf("#else\n");
+ printf("#define PTR .long\n");
+ printf("#define ALGN .align 4\n");
+ printf("#endif\n");
+
+ printf(".data\n");
+}
+
/* uncompress a compressed symbol. When this function is called, the best table
* might still be compressed itself, so the function needs to be recursive */
static int expand_symbol(unsigned char *data, int len, char *result)
@@ -257,6 +271,25 @@ static int expand_symbol(unsigned char *
return total;
}

+/* this function writes an empty assembly output with just the definitions
+ * of the variables */
+
+static void write_src_zero_pass(void)
+{
+ output_header();
+
+ output_label("kallsyms_addresses");
+ output_label("kallsyms_num_syms");
+ output_label("kallsyms_names");
+ output_label("kallsyms_markers");
+ output_label("kallsyms_token_table");
+ output_label("kallsyms_token_index");
+
+ printf("\t.byte\t0\n");
+}
+
+/* this one writes the real deal */
+
static void
write_src(void)
{
@@ -265,16 +298,7 @@ write_src(void)
unsigned int *markers;
char buf[KSYM_NAME_LEN+1];

- printf("#include <asm/types.h>\n");
- printf("#if BITS_PER_LONG == 64\n");
- printf("#define PTR .quad\n");
- printf("#define ALGN .align 8\n");
- printf("#else\n");
- printf("#define PTR .long\n");
- printf("#define ALGN .align 4\n");
- printf("#endif\n");
-
- printf(".data\n");
+ output_header();

output_label("kallsyms_addresses");
valid = 0;
@@ -672,11 +696,18 @@ static void optimize_token_table(void)
int
main(int argc, char **argv)
{
- if (argc == 2 && strcmp(argv[1], "--all-symbols") == 0)
- all_symbols = 1;
- else if (argc != 1)
- usage();
+ int i;

+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--all-symbols") == 0)
+ all_symbols = 1;
+ else if(strcmp(argv[i], "-0") == 0) {
+ write_src_zero_pass();
+ return 0;
+ } else
+ usage();
+ }
+
read_map(stdin);
optimize_token_table();
write_src();