Commit e84048aa authored by Quentin Casasnovas's avatar Quentin Casasnovas Committed by Rusty Russell

modpost: fix extable entry size calculation.

As Guenter pointed out, we were never really calculating the extable entry
size because the pointer arithmetic was simply wrong.  We want to check
we're handling the second relocation in __ex_table to infer an entry size,
but we were using (void*) pointers instead of Elf_Rel[a]* ones.

This fixes the problem by moving that check in the caller (since we can
deal with different types of relocations) and add is_second_extable_reloc()
to make the whole thing more readable.
Signed-off-by: default avatarQuentin Casasnovas <quentin.casasnovas@oracle.com>
Reported-by: default avatarGuenter Roeck <linux@roeck-us.net>
CC: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent d3df4de7
...@@ -1511,8 +1511,7 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde ...@@ -1511,8 +1511,7 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde
* to know the sizeof(struct exception_table_entry) for the target architecture. * to know the sizeof(struct exception_table_entry) for the target architecture.
*/ */
static unsigned int extable_entry_size = 0; static unsigned int extable_entry_size = 0;
static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
const void* start, const void* cur)
{ {
/* /*
* If we're currently checking the second relocation within __ex_table, * If we're currently checking the second relocation within __ex_table,
...@@ -1523,10 +1522,10 @@ static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, ...@@ -1523,10 +1522,10 @@ static void find_extable_entry_size(const char* const sec, const Elf_Rela* r,
* seems to go with different sized types. Not pretty but better than * seems to go with different sized types. Not pretty but better than
* hard-coding the size for every architecture.. * hard-coding the size for every architecture..
*/ */
if (!extable_entry_size && cur == start + 1 && if (!extable_entry_size)
strcmp("__ex_table", sec) == 0)
extable_entry_size = r->r_offset * 2; extable_entry_size = r->r_offset * 2;
} }
static inline bool is_extable_fault_address(Elf_Rela *r) static inline bool is_extable_fault_address(Elf_Rela *r)
{ {
/* /*
...@@ -1541,6 +1540,9 @@ static inline bool is_extable_fault_address(Elf_Rela *r) ...@@ -1541,6 +1540,9 @@ static inline bool is_extable_fault_address(Elf_Rela *r)
(r->r_offset % extable_entry_size == 0)); (r->r_offset % extable_entry_size == 0));
} }
#define is_second_extable_reloc(Start, Cur, Sec) \
(((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
static void report_extable_warnings(const char* modname, struct elf_info* elf, static void report_extable_warnings(const char* modname, struct elf_info* elf,
const struct sectioncheck* const mismatch, const struct sectioncheck* const mismatch,
Elf_Rela* r, Elf_Sym* sym, Elf_Rela* r, Elf_Sym* sym,
...@@ -1769,7 +1771,8 @@ static void section_rela(const char *modname, struct elf_info *elf, ...@@ -1769,7 +1771,8 @@ static void section_rela(const char *modname, struct elf_info *elf,
/* Skip special sections */ /* Skip special sections */
if (is_shndx_special(sym->st_shndx)) if (is_shndx_special(sym->st_shndx))
continue; continue;
find_extable_entry_size(fromsec, &r, start, rela); if (is_second_extable_reloc(start, rela, fromsec))
find_extable_entry_size(fromsec, &r);
check_section_mismatch(modname, elf, &r, sym, fromsec); check_section_mismatch(modname, elf, &r, sym, fromsec);
} }
} }
...@@ -1828,7 +1831,8 @@ static void section_rel(const char *modname, struct elf_info *elf, ...@@ -1828,7 +1831,8 @@ static void section_rel(const char *modname, struct elf_info *elf,
/* Skip special sections */ /* Skip special sections */
if (is_shndx_special(sym->st_shndx)) if (is_shndx_special(sym->st_shndx))
continue; continue;
find_extable_entry_size(fromsec, &r, start, rel); if (is_second_extable_reloc(start, rel, fromsec))
find_extable_entry_size(fromsec, &r);
check_section_mismatch(modname, elf, &r, sym, fromsec); check_section_mismatch(modname, elf, &r, sym, fromsec);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment