module_64.c (c1f3ee120bb61045b1c0a3ead620d1d65af47130) module_64.c (f0c426bc3557a93e9d2f2863fda1e2042f942a60)
1/* Kernel module help for PPC64.
2 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8

--- 87 unchanged lines hidden (view full) ---

96 _count_relocs++;
97 r_info = ELF64_R_SYM(rela[i].r_info);
98 r_addend = rela[i].r_addend;
99 }
100
101 return _count_relocs;
102}
103
1/* Kernel module help for PPC64.
2 Copyright (C) 2001, 2003 Rusty Russell IBM Corporation.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8

--- 87 unchanged lines hidden (view full) ---

96 _count_relocs++;
97 r_info = ELF64_R_SYM(rela[i].r_info);
98 r_addend = rela[i].r_addend;
99 }
100
101 return _count_relocs;
102}
103
104void *module_alloc(unsigned long size)
105{
106 if (size == 0)
107 return NULL;
108
109 return vmalloc_exec(size);
110}
111
112/* Free memory returned from module_alloc */
113void module_free(struct module *mod, void *module_region)
114{
115 vfree(module_region);
116 /* FIXME: If module_region == mod->init_region, trim exception
117 table entries. */
118}
119
120static int relacmp(const void *_x, const void *_y)
121{
122 const Elf64_Rela *x, *y;
123
124 y = (Elf64_Rela *)_x;
125 x = (Elf64_Rela *)_y;
126
127 /* Compare the entire r_info (as opposed to ELF64_R_SYM(r_info) only) to

--- 333 unchanged lines hidden (view full) ---

461 me->name,
462 (unsigned long)ELF64_R_TYPE(rela[i].r_info));
463 return -ENOEXEC;
464 }
465 }
466
467 return 0;
468}
104static int relacmp(const void *_x, const void *_y)
105{
106 const Elf64_Rela *x, *y;
107
108 y = (Elf64_Rela *)_x;
109 x = (Elf64_Rela *)_y;
110
111 /* Compare the entire r_info (as opposed to ELF64_R_SYM(r_info) only) to

--- 333 unchanged lines hidden (view full) ---

445 me->name,
446 (unsigned long)ELF64_R_TYPE(rela[i].r_info));
447 return -ENOEXEC;
448 }
449 }
450
451 return 0;
452}
469
470LIST_HEAD(module_bug_list);
471
472static const Elf_Shdr *find_section(const Elf_Ehdr *hdr,
473 const Elf_Shdr *sechdrs,
474 const char *name)
475{
476 char *secstrings;
477 unsigned int i;
478
479 secstrings = (char *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
480 for (i = 1; i < hdr->e_shnum; i++)
481 if (strcmp(secstrings+sechdrs[i].sh_name, name) == 0)
482 return &sechdrs[i];
483 return NULL;
484}
485
486int module_finalize(const Elf_Ehdr *hdr,
487 const Elf_Shdr *sechdrs, struct module *me)
488{
489 const Elf_Shdr *sect;
490 int err;
491
492 err = module_bug_finalize(hdr, sechdrs, me);
493 if (err)
494 return err;
495
496 /* Apply feature fixups */
497 sect = find_section(hdr, sechdrs, "__ftr_fixup");
498 if (sect != NULL)
499 do_feature_fixups(cur_cpu_spec->cpu_features,
500 (void *)sect->sh_addr,
501 (void *)sect->sh_addr + sect->sh_size);
502
503 sect = find_section(hdr, sechdrs, "__fw_ftr_fixup");
504 if (sect != NULL)
505 do_feature_fixups(powerpc_firmware_features,
506 (void *)sect->sh_addr,
507 (void *)sect->sh_addr + sect->sh_size);
508
509 return 0;
510}
511
512void module_arch_cleanup(struct module *mod)
513{
514 module_bug_cleanup(mod);
515}
516
517struct bug_entry *module_find_bug(unsigned long bugaddr)
518{
519 struct mod_arch_specific *mod;
520 unsigned int i;
521 struct bug_entry *bug;
522
523 list_for_each_entry(mod, &module_bug_list, bug_list) {
524 bug = mod->bug_table;
525 for (i = 0; i < mod->num_bugs; ++i, ++bug)
526 if (bugaddr == bug->bug_addr)
527 return bug;
528 }
529 return NULL;
530}