aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
authorQuentin Casasnovas <quentin.casasnovas@oracle.com>2015-04-15 23:35:36 -0400
committerRusty Russell <rusty@rustcorp.com.au>2015-04-22 04:01:32 -0400
commite84048aa173f2403fa468cb189f101b57fece539 (patch)
tree09f4b1b0db1513c75e46eeffd4369bd2f8021106 /scripts/mod
parentd3df4de7eb095cc4334759a5e65bf3bfb4be04f1 (diff)
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: 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>
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 93bb87d0e17d..fd949770da0c 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1511,8 +1511,7 @@ static int is_executable_section(struct elf_info* elf, unsigned int section_inde
1511 * to know the sizeof(struct exception_table_entry) for the target architecture. 1511 * to know the sizeof(struct exception_table_entry) for the target architecture.
1512 */ 1512 */
1513static unsigned int extable_entry_size = 0; 1513static unsigned int extable_entry_size = 0;
1514static void find_extable_entry_size(const char* const sec, const Elf_Rela* r, 1514static void find_extable_entry_size(const char* const sec, const Elf_Rela* r)
1515 const void* start, const void* cur)
1516{ 1515{
1517 /* 1516 /*
1518 * If we're currently checking the second relocation within __ex_table, 1517 * 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 * seems to go with different sized types. Not pretty but better than 1522 * seems to go with different sized types. Not pretty but better than
1524 * hard-coding the size for every architecture.. 1523 * hard-coding the size for every architecture..
1525 */ 1524 */
1526 if (!extable_entry_size && cur == start + 1 && 1525 if (!extable_entry_size)
1527 strcmp("__ex_table", sec) == 0)
1528 extable_entry_size = r->r_offset * 2; 1526 extable_entry_size = r->r_offset * 2;
1529} 1527}
1528
1530static inline bool is_extable_fault_address(Elf_Rela *r) 1529static inline bool is_extable_fault_address(Elf_Rela *r)
1531{ 1530{
1532 /* 1531 /*
@@ -1541,6 +1540,9 @@ static inline bool is_extable_fault_address(Elf_Rela *r)
1541 (r->r_offset % extable_entry_size == 0)); 1540 (r->r_offset % extable_entry_size == 0));
1542} 1541}
1543 1542
1543#define is_second_extable_reloc(Start, Cur, Sec) \
1544 (((Cur) == (Start) + 1) && (strcmp("__ex_table", (Sec)) == 0))
1545
1544static void report_extable_warnings(const char* modname, struct elf_info* elf, 1546static void report_extable_warnings(const char* modname, struct elf_info* elf,
1545 const struct sectioncheck* const mismatch, 1547 const struct sectioncheck* const mismatch,
1546 Elf_Rela* r, Elf_Sym* sym, 1548 Elf_Rela* r, Elf_Sym* sym,
@@ -1769,7 +1771,8 @@ static void section_rela(const char *modname, struct elf_info *elf,
1769 /* Skip special sections */ 1771 /* Skip special sections */
1770 if (is_shndx_special(sym->st_shndx)) 1772 if (is_shndx_special(sym->st_shndx))
1771 continue; 1773 continue;
1772 find_extable_entry_size(fromsec, &r, start, rela); 1774 if (is_second_extable_reloc(start, rela, fromsec))
1775 find_extable_entry_size(fromsec, &r);
1773 check_section_mismatch(modname, elf, &r, sym, fromsec); 1776 check_section_mismatch(modname, elf, &r, sym, fromsec);
1774 } 1777 }
1775} 1778}
@@ -1828,7 +1831,8 @@ static void section_rel(const char *modname, struct elf_info *elf,
1828 /* Skip special sections */ 1831 /* Skip special sections */
1829 if (is_shndx_special(sym->st_shndx)) 1832 if (is_shndx_special(sym->st_shndx))
1830 continue; 1833 continue;
1831 find_extable_entry_size(fromsec, &r, start, rel); 1834 if (is_second_extable_reloc(start, rel, fromsec))
1835 find_extable_entry_size(fromsec, &r);
1832 check_section_mismatch(modname, elf, &r, sym, fromsec); 1836 check_section_mismatch(modname, elf, &r, sym, fromsec);
1833 } 1837 }
1834} 1838}