1- /* $NetBSD: elf2ecoff.c,v 1.36 2025/03/30 14:13:59 tsutsui Exp $ */
1+ /* $NetBSD: elf2ecoff.c,v 1.36.2.1 2025/09/23 16:01:28 martin Exp $ */
22
33/*
44 * Copyright (c) 1997 Jonathan Stone
@@ -83,6 +83,8 @@ static char *saveRead(int, off_t, off_t, const char *);
8383static void safewrite (int , const void * , off_t , const char * );
8484static void copy (int , int , off_t , off_t );
8585static void combine (struct sect * , struct sect * , int );
86+ static size_t compute_stringsize (const Elf32_Sym * elf_syms , int nsymbols ,
87+ const char * elf_stringbase );
8688static void translate_syms (struct elf_syms * , struct ecoff_syms * );
8789static void elf_symbol_table_to_ecoff (int , int , struct ecoff32_exechdr * ,
8890 off_t , off_t , off_t , off_t );
@@ -715,7 +717,32 @@ elf_symbol_table_to_ecoff(int out, int in, struct ecoff32_exechdr *ep,
715717 pad16 (out , padding , "symbols: padding" );
716718}
717719
720+ /*
721+ * Compute the total ECOFF string table size.
722+ * ELF .strtab can share or overlap substrings,
723+ * but ECOFF table needs to have duplicated names.
724+ */
725+ static size_t
726+ compute_stringsize (const Elf32_Sym * elf_syms , int nsyms ,
727+ const char * stringbase )
728+ {
729+ size_t stringsize = 0 ;
730+ int i ;
731+
732+ for (i = 0 ; i < nsyms ; i ++ ) {
733+ const Elf32_Sym * esym = & elf_syms [i ];
734+ const char * name ;
718735
736+ if (ELF32_ST_BIND (esym -> st_info ) == STB_LOCAL )
737+ continue ;
738+ name = stringbase + esym -> st_name ;
739+ stringsize += strlen (name ) + 1 ;
740+ }
741+ if (stringsize == 0 )
742+ stringsize = 1 ; /* for NUL */
743+
744+ return stringsize ;
745+ }
719746
720747/*
721748 * In-memory translation of ELF symbols to ECOFF.
@@ -727,7 +754,7 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
727754 int i ;
728755 char * oldstringbase ;
729756 char * newstrings , * nsp ;
730-
757+ size_t stringsize ;
731758 int nsyms , idx ;
732759
733760 nsyms = elfp -> nsymbols ;
@@ -739,43 +766,56 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
739766 ecoffp -> nsymbols = 0 ;
740767 ecoffp -> ecoff_syms = malloc (sizeof (struct ecoff_extsym ) * nsyms );
741768
742- /* we are going to be no bigger than the ELF symbol table. */
743- ecoffp -> stringsize = elfp -> stringsize ;
744- ecoffp -> stringtab = malloc (elfp -> stringsize );
745-
746- newstrings = (char * ) ecoffp -> stringtab ;
747- nsp = (char * ) ecoffp -> stringtab ;
769+ /* ECOFF string table could be bigger than the ELF one. */
770+ stringsize = compute_stringsize (elfp -> elf_syms , nsyms , oldstringbase );
771+ if (debug ) {
772+ fprintf (stderr ,
773+ "%zu (0x%zx) bytes ELF string table\n" ,
774+ (size_t )elfp -> stringsize , (size_t )elfp -> stringsize );
775+ fprintf (stderr ,
776+ "%zu (0x%zx) bytes required for ECOFF string table\n" ,
777+ stringsize , stringsize );
778+ }
779+ newstrings = malloc (stringsize );
748780 if (newstrings == NULL )
749781 errx (1 , "No memory for new string table" );
750- /* Copy and translate symbols... */
782+ /* Copy and translate symbols... */
783+ nsp = newstrings ;
751784 idx = 0 ;
752785 for (i = 0 ; i < nsyms ; i ++ ) {
753- int binding ;
786+ const Elf32_Sym * esym = & elfp -> elf_syms [i ];
787+ const char * name ;
788+ size_t namelen ;
754789
755- binding = ELF32_ST_BIND ((elfp -> elf_syms [i ].st_info ));
756-
757- /* skip strange symbols */
758- if (binding == 0 ) {
790+ if (ELF32_ST_BIND (esym -> st_info ) == STB_LOCAL )
759791 continue ;
760- }
792+ name = oldstringbase + esym -> st_name ;
793+ namelen = strlen (name ) + 1 ;
794+ if (nsp + namelen > newstrings + stringsize )
795+ errx (1 , "ECOFF string table overflow" );
761796 /* Copy the symbol into the new table */
762- strcpy (nsp , oldstringbase + elfp -> elf_syms [ i ]. st_name );
797+ strcpy (nsp , name );
763798 ecoffp -> ecoff_syms [idx ].es_strindex = nsp - newstrings ;
764- nsp += strlen ( nsp ) + 1 ;
799+ nsp += namelen ;
765800
766801 /* translate symbol types to ECOFF XXX */
767802 ecoffp -> ecoff_syms [idx ].es_type = 1 ;
768803 ecoffp -> ecoff_syms [idx ].es_class = 5 ;
769804
770805 /* Symbol values in executables should be compatible. */
771- ecoffp -> ecoff_syms [idx ].es_value = elfp -> elf_syms [ i ]. st_value ;
806+ ecoffp -> ecoff_syms [idx ].es_value = esym -> st_value ;
772807 ecoffp -> ecoff_syms [idx ].es_symauxindex = 0xfffff ;
773808
774809 idx ++ ;
775810 }
776811
777812 ecoffp -> nsymbols = idx ;
813+ ecoffp -> stringtab = newstrings ;
778814 ecoffp -> stringsize = nsp - newstrings ;
815+ if (debug )
816+ fprintf (stderr ,
817+ "%zu (0x%zx) bytes used for ECOFF string table\n" ,
818+ (size_t )ecoffp -> stringsize , (size_t )ecoffp -> stringsize );
779819}
780820/*
781821 * pad to a 16-byte boundary
0 commit comments