link_elf_obj: Handle init_array sections in KLDs
Reuse existing handling for .ctors, print a warning if multiple constructor sections are present. Destructors are not handled as of yet. This is required for KASAN. Reviewed by: kib MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29049
This commit is contained in:
parent
23553d6b94
commit
5e6989ba4f
@ -386,6 +386,8 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
|
|||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
case SHT_X86_64_UNWIND:
|
case SHT_X86_64_UNWIND:
|
||||||
#endif
|
#endif
|
||||||
|
case SHT_INIT_ARRAY:
|
||||||
|
case SHT_FINI_ARRAY:
|
||||||
/* Ignore sections not loaded by the loader. */
|
/* Ignore sections not loaded by the loader. */
|
||||||
if (shdr[i].sh_addr == 0)
|
if (shdr[i].sh_addr == 0)
|
||||||
break;
|
break;
|
||||||
@ -470,6 +472,7 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
|
|||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
case SHT_X86_64_UNWIND:
|
case SHT_X86_64_UNWIND:
|
||||||
#endif
|
#endif
|
||||||
|
case SHT_FINI_ARRAY:
|
||||||
if (shdr[i].sh_addr == 0)
|
if (shdr[i].sh_addr == 0)
|
||||||
break;
|
break;
|
||||||
ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
|
ef->progtab[pb].addr = (void *)shdr[i].sh_addr;
|
||||||
@ -479,6 +482,10 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
|
|||||||
else if (shdr[i].sh_type == SHT_X86_64_UNWIND)
|
else if (shdr[i].sh_type == SHT_X86_64_UNWIND)
|
||||||
ef->progtab[pb].name = "<<UNWIND>>";
|
ef->progtab[pb].name = "<<UNWIND>>";
|
||||||
#endif
|
#endif
|
||||||
|
else if (shdr[i].sh_type == SHT_INIT_ARRAY)
|
||||||
|
ef->progtab[pb].name = "<<INIT_ARRAY>>";
|
||||||
|
else if (shdr[i].sh_type == SHT_FINI_ARRAY)
|
||||||
|
ef->progtab[pb].name = "<<FINI_ARRAY>>";
|
||||||
else
|
else
|
||||||
ef->progtab[pb].name = "<<NOBITS>>";
|
ef->progtab[pb].name = "<<NOBITS>>";
|
||||||
ef->progtab[pb].size = shdr[i].sh_size;
|
ef->progtab[pb].size = shdr[i].sh_size;
|
||||||
@ -525,10 +532,17 @@ link_elf_link_preload(linker_class_t cls, const char *filename,
|
|||||||
vnet_data_copy(vnet_data, shdr[i].sh_size);
|
vnet_data_copy(vnet_data, shdr[i].sh_size);
|
||||||
ef->progtab[pb].addr = vnet_data;
|
ef->progtab[pb].addr = vnet_data;
|
||||||
#endif
|
#endif
|
||||||
} else if (ef->progtab[pb].name != NULL &&
|
} else if ((ef->progtab[pb].name != NULL &&
|
||||||
!strcmp(ef->progtab[pb].name, ".ctors")) {
|
strcmp(ef->progtab[pb].name, ".ctors") == 0) ||
|
||||||
lf->ctors_addr = ef->progtab[pb].addr;
|
shdr[i].sh_type == SHT_INIT_ARRAY) {
|
||||||
lf->ctors_size = shdr[i].sh_size;
|
if (lf->ctors_addr != 0) {
|
||||||
|
printf(
|
||||||
|
"%s: multiple ctor sections in %s\n",
|
||||||
|
__func__, filename);
|
||||||
|
} else {
|
||||||
|
lf->ctors_addr = ef->progtab[pb].addr;
|
||||||
|
lf->ctors_size = shdr[i].sh_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all symbol values with the offset. */
|
/* Update all symbol values with the offset. */
|
||||||
@ -773,6 +787,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
|||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
case SHT_X86_64_UNWIND:
|
case SHT_X86_64_UNWIND:
|
||||||
#endif
|
#endif
|
||||||
|
case SHT_INIT_ARRAY:
|
||||||
|
case SHT_FINI_ARRAY:
|
||||||
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
||||||
break;
|
break;
|
||||||
ef->nprogtab++;
|
ef->nprogtab++;
|
||||||
@ -894,6 +910,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
|||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
case SHT_X86_64_UNWIND:
|
case SHT_X86_64_UNWIND:
|
||||||
#endif
|
#endif
|
||||||
|
case SHT_INIT_ARRAY:
|
||||||
|
case SHT_FINI_ARRAY:
|
||||||
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
||||||
break;
|
break;
|
||||||
alignmask = shdr[i].sh_addralign - 1;
|
alignmask = shdr[i].sh_addralign - 1;
|
||||||
@ -971,6 +989,8 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
|||||||
#ifdef __amd64__
|
#ifdef __amd64__
|
||||||
case SHT_X86_64_UNWIND:
|
case SHT_X86_64_UNWIND:
|
||||||
#endif
|
#endif
|
||||||
|
case SHT_INIT_ARRAY:
|
||||||
|
case SHT_FINI_ARRAY:
|
||||||
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
if ((shdr[i].sh_flags & SHF_ALLOC) == 0)
|
||||||
break;
|
break;
|
||||||
alignmask = shdr[i].sh_addralign - 1;
|
alignmask = shdr[i].sh_addralign - 1;
|
||||||
@ -979,9 +999,18 @@ link_elf_load_file(linker_class_t cls, const char *filename,
|
|||||||
if (ef->shstrtab != NULL && shdr[i].sh_name != 0) {
|
if (ef->shstrtab != NULL && shdr[i].sh_name != 0) {
|
||||||
ef->progtab[pb].name =
|
ef->progtab[pb].name =
|
||||||
ef->shstrtab + shdr[i].sh_name;
|
ef->shstrtab + shdr[i].sh_name;
|
||||||
if (!strcmp(ef->progtab[pb].name, ".ctors")) {
|
if (!strcmp(ef->progtab[pb].name, ".ctors") ||
|
||||||
lf->ctors_addr = (caddr_t)mapbase;
|
shdr[i].sh_type == SHT_INIT_ARRAY) {
|
||||||
lf->ctors_size = shdr[i].sh_size;
|
if (lf->ctors_addr != 0) {
|
||||||
|
printf(
|
||||||
|
"%s: multiple ctor sections in %s\n",
|
||||||
|
__func__, filename);
|
||||||
|
} else {
|
||||||
|
lf->ctors_addr =
|
||||||
|
(caddr_t)mapbase;
|
||||||
|
lf->ctors_size =
|
||||||
|
shdr[i].sh_size;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (shdr[i].sh_type == SHT_PROGBITS)
|
} else if (shdr[i].sh_type == SHT_PROGBITS)
|
||||||
ef->progtab[pb].name = "<<PROGBITS>>";
|
ef->progtab[pb].name = "<<PROGBITS>>";
|
||||||
|
Loading…
Reference in New Issue
Block a user