Skip to content

Commit

Permalink
modpost: fix extable entry size calculation.
Browse files Browse the repository at this point in the history
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: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Reported-by: Guenter Roeck <linux@roeck-us.net>
CC: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
Quentin Casasnovas authored and Rusty Russell committed Apr 22, 2015
1 parent d3df4de commit e84048a
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions scripts/mod/modpost.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
static unsigned int extable_entry_size = 0;
static void find_extable_entry_size(const char* const sec, const Elf_Rela* r,
const void* start, const void* cur)
static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
{
/*
* If we're currently checking the second relocation within __ex_table,
Expand All @@ -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
* hard-coding the size for every architecture..
*/
if (!extable_entry_size && cur == start + 1 &&
strcmp("__ex_table", sec) == 0)
if (!extable_entry_size)
extable_entry_size = r->r_offset * 2;
}

static inline bool is_extable_fault_address(Elf_Rela *r)
{
/*
Expand All @@ -1541,6 +1540,9 @@ static inline bool is_extable_fault_address(Elf_Rela *r)
(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,
const struct sectioncheck* const mismatch,
Elf_Rela* r, Elf_Sym* sym,
Expand Down Expand Up @@ -1769,7 +1771,8 @@ static void section_rela(const char *modname, struct elf_info *elf,
/* Skip special sections */
if (is_shndx_special(sym->st_shndx))
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);
}
}
Expand Down Expand Up @@ -1828,7 +1831,8 @@ static void section_rel(const char *modname, struct elf_info *elf,
/* Skip special sections */
if (is_shndx_special(sym->st_shndx))
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);
}
}
Expand Down

0 comments on commit e84048a

Please sign in to comment.