{"id":22,"date":"2009-04-09T04:22:00","date_gmt":"2009-04-09T11:22:00","guid":{"rendered":"http:\/\/samueldotj.com\/blog\/?p=22"},"modified":"2013-09-04T15:08:08","modified_gmt":"2013-09-04T22:08:08","slug":"unreferenced-symbols-export_symbol","status":"publish","type":"post","link":"http:\/\/samueldotj.com\/blog\/unreferenced-symbols-export_symbol\/","title":{"rendered":"Unreferenced symbols &#8211; EXPORT_SYMBOL"},"content":{"rendered":"<p>I wrote ACPI driver for Ace and try to load it into kernel. It was failing with the error message symbol not found.<\/p>\n<p>The log file content says <strong>AcpiGetName <\/strong>was not found.<br \/>\n[shell]<br \/>\n$ cat log.txt<br \/>\nDriver for id acpi : acpi.sys<br \/>\n..\/src\/kernel\/pm\/elf.c:343:FindElfSymbolByName(): Symbol not found AcpiGetName(c01a2148:1869) string table c01aa619<br \/>\n[shell]<\/p>\n<p>After exploring the Acpi-CA source code and Ace kernel code, I couldn\u2019t figure out why the symbol is missing. Then I tried to dump the symbol table for Acpi library and kernel.sys.<br \/>\n[shell]<br \/>\n$ nm build\/default\/src\/kernel\/libacpi.a | grep GetName<br \/>\nU AcpiExGetNameString<br \/>\n000001e3 T AcpiExGetNameString<br \/>\n000001b7 T AcpiPsGetName<br \/>\n000000f4 T AcpiGetName<\/p>\n<p>$ nm build\/default\/src\/kernel\/kernel.sys | grep GetName<br \/>\nc0135163 T AcpiExGetNameString<br \/>\nc0137bfb T AcpiPsGetName<br \/>\n[\/shell]<\/p>\n<p>It is obvious during kernel link process some how the linker is losing <em>AcpiGetName<\/em>. Within few seconds I realized that the linker is doing optimization on the output to remove unreferenced sections. So I googled for how to avoid this and found <strong>&#8211;no-gc-sections<\/strong> is the ld option to do it. However even after giving this option to linker to was removing the unreferenced symbols; I kept on trying to find a solution for making the linker to include unreferenced symbols in the output\u2026 I didn\u2019t find the solution.<br \/>\nThen I started thinking how linux kernel is avoiding this problem and I it flashed seeing EXPORT_SYMBOL kind of macro in some source. So I googled for it and got the answer \u2013 use the symbol in storage, so that it will be referenced, so that linker will include it in the output.<br \/>\n[c]<br \/>\nstruct kernel_symbol<br \/>\n{<br \/>\n   unsigned long symbol;<br \/>\n   char * name;<br \/>\n};<\/p>\n<p>#ifndef MODULE_SYMBOL_PREFIX<br \/>\n#define MODULE_SYMBOL_PREFIX \u201c\u201d<br \/>\n#endif<\/p>\n<p>#define __EXPORT_SYMBOL(sym, sec) \\<br \/>\nstatic const char __kstrtab_##sym[] \\<br \/>\n__attribute__((section(&#8220;__ksymtab_strings&#8221;))) \\<br \/>\n= MODULE_SYMBOL_PREFIX#sym; \\<br \/>\nstatic const struct kernel_symbol __ksymtab_##sym \\<br \/>\n__attribute__((section(&#8220;__ksymtab&#8221; sec), unused)) \\<br \/>\n= { (unsigned long)&#038;sym, __kstrtab_##sym }<\/p>\n<p>#define EXPORT_SYMBOL(sym) \\<br \/>\n__EXPORT_SYMBOL(sym, &#8220;&#8221;)<\/p>\n<p>[\/c]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wrote ACPI driver for Ace and try to load it into kernel. It was failing with the error message symbol not found. The log file content says AcpiGetName was not found. [shell] $ cat log.txt Driver for id acpi : acpi.sys ..\/src\/kernel\/pm\/elf.c:343:FindElfSymbolByName(): Symbol not found AcpiGetName(c01a2148:1869) string table c01aa619 [shell] After exploring the Acpi-CA [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,3,9,5,4],"tags":[],"class_list":["post-22","post","type-post","status-publish","format-standard","hentry","category-ace","category-c","category-gcc","category-programming","category-tools"],"_links":{"self":[{"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/posts\/22","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/comments?post=22"}],"version-history":[{"count":3,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/posts\/22\/revisions"}],"predecessor-version":[{"id":200,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/posts\/22\/revisions\/200"}],"wp:attachment":[{"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/media?parent=22"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/categories?post=22"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/samueldotj.com\/blog\/wp-json\/wp\/v2\/tags?post=22"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}