Hi, On Tue, 2023-04-11 at 16:12 +0800, Ying Huang wrote: > From: Ying Huang <ying.hu...@oss.cipunited.com> > > add some check related functions > --- > backends/mips_init.c | 3 +++ > backends/mips_symbol.c | 33 +++++++++++++++++++++++++++++++++ > libebl/eblrelocvaliduse.c | 8 ++++++-- > src/elflint.c | 23 ++++++++++++++++++++--- > 4 files changed, 62 insertions(+), 5 deletions(-) > > diff --git a/backends/mips_init.c b/backends/mips_init.c > index 5bba822b..4c2f21b9 100644 > --- a/backends/mips_init.c > +++ b/backends/mips_init.c > @@ -51,6 +51,9 @@ mips_init (Elf *elf __attribute__ ((unused)), > HOOK (eh, segment_type_name); > HOOK (eh, dynamic_tag_check); > HOOK (eh, dynamic_tag_name); > + HOOK (eh, machine_section_flag_check); > HOOK (eh, check_object_attribute); > + HOOK (eh, check_special_symbol); > + HOOK (eh, check_reloc_target_type); > return eh; > }
OK. But see below for hooking reloc_valid_use > diff --git a/backends/mips_symbol.c b/backends/mips_symbol.c > index e760d58d..8787fcee 100644 > --- a/backends/mips_symbol.c > +++ b/backends/mips_symbol.c > @@ -158,6 +158,39 @@ mips_section_type_name (int type, > return NULL; > } > > +bool > +mips_check_reloc_target_type (Ebl *ebl __attribute__ ((unused)), Elf64_Word > sh_type) > +{ > + return (sh_type == SHT_MIPS_DWARF); > +} OK > +/* Check whether given symbol's st_value and st_size are OK despite failing > + normal checks. */ > +bool > +mips_check_special_symbol (Elf *elf, > + const GElf_Sym *sym __attribute__ ((unused)), > + const char *name __attribute__ ((unused)), > + const GElf_Shdr *destshdr) > +{ > + size_t shstrndx; > + if (elf_getshdrstrndx (elf, &shstrndx) != 0) > + return false; > + const char *sname = elf_strptr (elf, shstrndx, destshdr->sh_name); > + if (sname == NULL) > + return false; > + return (strcmp (sname, ".got") == 0 || strcmp (sname, ".bss") == 0); > +} Could you add a comment why .got and .bss are special in this case? > +/* Check whether SHF_MASKPROC flags are valid. */ > +bool > +mips_machine_section_flag_check (GElf_Xword sh_flags) > +{ > + return ((sh_flags &~ (SHF_MIPS_GPREL | > + SHF_MIPS_MERGE | > + SHF_MIPS_ADDR | > + SHF_MIPS_STRINGS)) == 0); > +} OK. But see below for checking other SHF_MIPS flags. > /* Check whether machine flags are valid. */ > bool > mips_machine_flag_check (GElf_Word flags) > diff --git a/libebl/eblrelocvaliduse.c b/libebl/eblrelocvaliduse.c > index f0bed345..44b8d300 100644 > --- a/libebl/eblrelocvaliduse.c > +++ b/libebl/eblrelocvaliduse.c > @@ -32,10 +32,14 @@ > #endif > > #include <libeblP.h> > - > +#include <libelfP.h> > > bool > ebl_reloc_valid_use (Ebl *ebl, int reloc) > { > - return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, reloc) : false; > + int relocNew = reloc; > + GElf_Ehdr ehdr; > + if(ebl->elf->class == ELFCLASS64 && gelf_getehdr(ebl->elf, &ehdr) != NULL > && ehdr.e_machine == EM_MIPS) > + relocNew = ELF64_MIPS_R_TYPE(reloc); > + return ebl != NULL ? ebl->reloc_valid_use (ebl->elf, relocNew) : false; > } This should be a mips reloc_valid_use hook. > diff --git a/src/elflint.c b/src/elflint.c > index dd42dcb4..04f1ee92 100644 > --- a/src/elflint.c > +++ b/src/elflint.c > @@ -935,7 +935,10 @@ section [%2d] '%s': symbol %zu (%s): non-local symbol > outside range described in > } > > if (GELF_ST_TYPE (sym->st_info) == STT_SECTION > - && GELF_ST_BIND (sym->st_info) != STB_LOCAL) > + && GELF_ST_BIND (sym->st_info) != STB_LOCAL > + && ehdr->e_machine != EM_MIPS > + && strcmp (name, "_DYNAMIC_LINK") != 0 > + && strcmp (name, "_DYNAMIC_LINKING") != 0) Could you add a comment here about both symbols not being local on MIPS? > ERROR (_("\ > section [%2d] '%s': symbol %zu (%s): non-local section symbol\n"), > idx, section_name (ebl, idx), cnt, name); > @@ -3789,6 +3792,12 @@ cannot get section header for section [%2zu] '%s': > %s\n"), > && ebl_bss_plt_p (ebl)) > good_type = SHT_NOBITS; > > + if (ehdr->e_machine == EM_MIPS > + && (strstr(special_sections[s].name, ".debug") != NULL)) > + { > + good_type = SHT_MIPS_DWARF; > + } OK. You don't need explicit brackets here > /* In a debuginfo file, any normal section can be SHT_NOBITS. > This is only invalid for DWARF sections and .shstrtab. */ > if (shdr->sh_type != good_type > @@ -3953,8 +3962,16 @@ section [%2zu] '%s': size not multiple of entry > size\n"), > sh_flags &= ~(GElf_Xword) SHF_MASKPROC; > } > if (sh_flags & SHF_MASKOS) > - if (gnuld) > - sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN; > + { > + if (gnuld) > + sh_flags &= ~(GElf_Xword) SHF_GNU_RETAIN; > + if (ehdr->e_machine == EM_MIPS) > + { > + if(sh_flags == SHF_MIPS_NOSTRIP || sh_flags == SHF_MIPS_LOCAL > + || sh_flags == SHF_MIPS_NAMES || sh_flags == SHF_MIPS_NODUPE) > + sh_flags &= ~shdr->sh_flags; > + } > + } > if (sh_flags != 0) > ERROR (_("section [%2zu] '%s' contains unknown flag(s)" > " %#" PRIx64 "\n"), Can this be checked with the machine_section_flag_check hook? Thanks, Mark