{
struct module *mod;
char *p, *s;
-
+
mod = NOFAIL(malloc(sizeof(*mod)));
memset(mod, 0, sizeof(*mod));
p = NOFAIL(strdup(modname));
continue;
info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
- info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
+ info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
+ sechdrs[i].sh_size;
- info->strtab = (void *)hdr +
+ info->strtab = (void *)hdr +
sechdrs[sechdrs[i].sh_link].sh_offset;
}
if (!info->symtab_start) {
/* Ignore register directives. */
if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
break;
- if (symname[0] == '.') {
- char *munged = strdup(symname);
- munged[0] = '_';
- munged[1] = toupper(munged[1]);
- symname = munged;
- }
+ if (symname[0] == '.') {
+ char *munged = strdup(symname);
+ munged[0] = '_';
+ munged[1] = toupper(munged[1]);
+ symname = munged;
+ }
}
#endif
-
+
if (memcmp(symname, MODULE_SYMBOL_PREFIX,
strlen(MODULE_SYMBOL_PREFIX)) == 0)
mod->unres = alloc_symbol(symname +
static int strrcmp(const char *s, const char *sub)
{
int slen, sublen;
-
+
if (!s || !sub)
return 1;
-
+
slen = strlen(s);
sublen = strlen(sub);
-
+
if ((slen == 0) || (sublen == 0))
return 1;
* tosec = .init.data
* fromsec = .data
* atsym =__param*
- *
+ *
* Pattern 2:
* Many drivers utilise a *_driver container with references to
* add, remove, probe functions etc.
"_probe_one",
NULL
};
-
+
/* Check for pattern 1 */
if (strcmp(tosec, ".init.data") != 0)
f1 = 0;
return f1;
/* Check for pattern 2 */
- if ((strcmp(tosec, ".init.text") != 0) &&
+ if ((strcmp(tosec, ".init.text") != 0) &&
(strcmp(tosec, ".exit.text") != 0))
f2 = 0;
if (strcmp(fromsec, ".data") != 0)
Elf_Addr afterdiff = ~0;
const char *secstrings = (void *)hdr +
elf->sechdrs[hdr->e_shstrndx].sh_offset;
-
+
*before = NULL;
*after = NULL;
const char *secstrings = (void *)hdr +
sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
-
+
find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
refsym = find_elf_symbol(elf, r.r_addend, sym);
refsymname = elf->strtab + refsym->st_name;
/* check whitelist - we may ignore it */
- if (before &&
+ if (before &&
secref_whitelist(secname, fromsec, elf->strtab + before->st_name))
return;
-
+
if (before && after) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"between '%s' (at offset 0x%llx) and '%s'\n",
} else if (before) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"after '%s' (at offset 0x%llx)\n",
- modname, secname, refsymname, fromsec,
+ modname, secname, refsymname, fromsec,
elf->strtab + before->st_name,
(long long)r.r_offset);
} else if (after) {
warn("%s - Section mismatch: reference to %s:%s from %s "
"before '%s' (at offset -0x%llx)\n",
- modname, secname, refsymname, fromsec,
+ modname, secname, refsymname, fromsec,
elf->strtab + before->st_name,
(long long)r.r_offset);
} else {
Elf_Shdr *sechdrs = elf->sechdrs;
const char *secstrings = (void *)hdr +
sechdrs[hdr->e_shstrndx].sh_offset;
-
+
/* Walk through all sections */
for (i = 0; i < hdr->e_shnum; i++) {
Elf_Rela *rela;
/**
* Identify sections from which references to a .init section is OK.
- *
+ *
* Unfortunately references to read only data that referenced .init
* sections had to be excluded. Almost all of these are false
* positives, they are created by gcc. The downside of excluding rodata
* is that there really are some user references from rodata to
* init code, e.g. drivers/video/vgacon.c:
- *
+ *
* const struct consw vga_con = {
* con_startup: vgacon_startup,
*
for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0)
return 1;
- for (s = namelist2; *s; s++)
+ for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
- for (s = namelist3; *s; s++)
+ for (s = namelist3; *s; s++)
if (strstr(*s, name) != NULL)
return 1;
return 0;
if (strcmp(name, ".exit.data") == 0)
return 1;
return 0;
-
+
}
/*
* Identify sections from which references to a .exit section is OK.
- *
+ *
* [OPD] Keith Ownes <kaos@sgi.com> commented:
* For our future {in}sanity, add a comment that this is the ppc .opd
* section, not the ia64 .opd section.
".unwind", /* Sample: IA_64.unwind.exit.text */
NULL
};
-
+
for (s = namelist1; *s; s++)
if (strcmp(*s, name) == 0)
return 1;
- for (s = namelist2; *s; s++)
+ for (s = namelist2; *s; s++)
if (strncmp(*s, name, strlen(*s)) == 0)
return 1;
- for (s = namelist3; *s; s++)
+ for (s = namelist3; *s; s++)
if (strstr(*s, name) != NULL)
return 1;
return 0;
char tmp[SZ];
int len;
va_list ap;
-
+
va_start(ap, fmt);
len = vsnprintf(tmp, SZ, fmt, ap);
if (buf->size - buf->pos < len + 1) {
return 0;
return 1;
}
-
+
static void write_dump(const char *fname)
{
struct buffer buf = { };
while (symbol) {
if (dump_sym(symbol))
buf_printf(&buf, "0x%08x\t%s\t%s\n",
- symbol->crc, symbol->name,
+ symbol->crc, symbol->name,
symbol->module->name);
symbol = symbol->next;
}