|
8 | 8 | #include <linux/module.h> |
9 | 9 | #include <linux/moduleloader.h> |
10 | 10 | #include <linux/ftrace.h> |
| 11 | +#include <linux/sort.h> |
11 | 12 |
|
12 | 13 | Elf_Addr module_emit_got_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr val) |
13 | 14 | { |
@@ -61,39 +62,38 @@ Elf_Addr module_emit_plt_entry(struct module *mod, Elf_Shdr *sechdrs, Elf_Addr v |
61 | 62 | return (Elf_Addr)&plt[nr]; |
62 | 63 | } |
63 | 64 |
|
64 | | -static int is_rela_equal(const Elf_Rela *x, const Elf_Rela *y) |
65 | | -{ |
66 | | - return x->r_info == y->r_info && x->r_addend == y->r_addend; |
67 | | -} |
| 65 | +#define cmp_3way(a, b) ((a) < (b) ? -1 : (a) > (b)) |
68 | 66 |
|
69 | | -static bool duplicate_rela(const Elf_Rela *rela, int idx) |
| 67 | +static int compare_rela(const void *x, const void *y) |
70 | 68 | { |
71 | | - int i; |
| 69 | + int ret; |
| 70 | + const Elf_Rela *rela_x = x, *rela_y = y; |
72 | 71 |
|
73 | | - for (i = 0; i < idx; i++) { |
74 | | - if (is_rela_equal(&rela[i], &rela[idx])) |
75 | | - return true; |
76 | | - } |
| 72 | + ret = cmp_3way(rela_x->r_info, rela_y->r_info); |
| 73 | + if (ret == 0) |
| 74 | + ret = cmp_3way(rela_x->r_addend, rela_y->r_addend); |
77 | 75 |
|
78 | | - return false; |
| 76 | + return ret; |
79 | 77 | } |
80 | 78 |
|
81 | 79 | static void count_max_entries(Elf_Rela *relas, int num, |
82 | 80 | unsigned int *plts, unsigned int *gots) |
83 | 81 | { |
84 | | - unsigned int i, type; |
| 82 | + unsigned int i; |
| 83 | + |
| 84 | + sort(relas, num, sizeof(Elf_Rela), compare_rela, NULL); |
85 | 85 |
|
86 | 86 | for (i = 0; i < num; i++) { |
87 | | - type = ELF_R_TYPE(relas[i].r_info); |
88 | | - switch (type) { |
| 87 | + if (i && !compare_rela(&relas[i-1], &relas[i])) |
| 88 | + continue; |
| 89 | + |
| 90 | + switch (ELF_R_TYPE(relas[i].r_info)) { |
89 | 91 | case R_LARCH_SOP_PUSH_PLT_PCREL: |
90 | 92 | case R_LARCH_B26: |
91 | | - if (!duplicate_rela(relas, i)) |
92 | | - (*plts)++; |
| 93 | + (*plts)++; |
93 | 94 | break; |
94 | 95 | case R_LARCH_GOT_PC_HI20: |
95 | | - if (!duplicate_rela(relas, i)) |
96 | | - (*gots)++; |
| 96 | + (*gots)++; |
97 | 97 | break; |
98 | 98 | default: |
99 | 99 | break; /* Do nothing. */ |
|
0 commit comments