1- /* $NetBSD: elf2ecoff.c,v 1.33 2017/02/24 17:19:14 christos Exp $ */
1+ /* $NetBSD: elf2ecoff.c,v 1.33.14.1 2025/09/23 16:37:04 martin Exp $ */
22
33/*
44 * Copyright (c) 1997 Jonathan Stone
@@ -74,14 +74,17 @@ struct ecoff_syms {
7474 char * stringtab ;
7575};
7676
77- static int debug = 0 ;
77+ int debug = 0 ;
78+
7879static int needswap ;
7980
8081static int phcmp (Elf32_Phdr * , Elf32_Phdr * );
8182static char * saveRead (int , off_t , off_t , const char * );
8283static void safewrite (int , const void * , off_t , const char * );
8384static void copy (int , int , off_t , off_t );
8485static 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 );
8588static void translate_syms (struct elf_syms * , struct ecoff_syms * );
8689static void elf_symbol_table_to_ecoff (int , int , struct ecoff32_exechdr * ,
8790 off_t , off_t , off_t , off_t );
@@ -246,7 +249,7 @@ main(int argc, char **argv)
246249 nbss .len = ph [i ].p_memsz - ph [i ].p_filesz ;
247250
248251 if (debug ) {
249- fprintf (stderr , " combinining PH %zu type %d "
252+ fprintf (stderr , " combining PH %zu type %d "
250253 "flags %#x with data, ndata = %d, "
251254 "nbss =%d\n" , i , ph [i ].p_type ,
252255 ph [i ].p_flags , ndata .len , nbss .len );
@@ -259,7 +262,7 @@ main(int argc, char **argv)
259262 ntxt .vaddr = ph [i ].p_vaddr ;
260263 ntxt .len = ph [i ].p_filesz ;
261264 if (debug ) {
262- fprintf (stderr , " combinining PH %zu type %d "
265+ fprintf (stderr , " combining PH %zu type %d "
263266 "flags %#x with text, len = %d\n" ,
264267 i , ph [i ].p_type , ph [i ].p_flags , ntxt .len );
265268 }
@@ -314,7 +317,7 @@ main(int argc, char **argv)
314317 ep .f .f_symptr = 0 ;
315318 ep .f .f_nsyms = sizeof (struct ecoff32_symhdr );
316319 ep .f .f_opthdr = sizeof ep .a ;
317- ep .f .f_flags = 0x100f ; /* Stripped, not sharable . */
320+ ep .f .f_flags = 0x100f ; /* Stripped, not shareable . */
318321
319322 memset (esecs , 0 , sizeof (esecs ));
320323
@@ -714,10 +717,35 @@ elf_symbol_table_to_ecoff(int out, int in, struct ecoff32_exechdr *ep,
714717 pad16 (out , padding , "symbols: padding" );
715718}
716719
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 ;
735+
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 */
717743
744+ return stringsize ;
745+ }
718746
719747/*
720- * In-memory translation of ELF symbosl to ECOFF.
748+ * In-memory translation of ELF symbols to ECOFF.
721749 */
722750static void
723751translate_syms (struct elf_syms * elfp , struct ecoff_syms * ecoffp )
@@ -726,7 +754,7 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
726754 int i ;
727755 char * oldstringbase ;
728756 char * newstrings , * nsp ;
729-
757+ size_t stringsize ;
730758 int nsyms , idx ;
731759
732760 nsyms = elfp -> nsymbols ;
@@ -738,43 +766,56 @@ translate_syms(struct elf_syms *elfp, struct ecoff_syms *ecoffp)
738766 ecoffp -> nsymbols = 0 ;
739767 ecoffp -> ecoff_syms = malloc (sizeof (struct ecoff_extsym ) * nsyms );
740768
741- /* we are going to be no bigger than the ELF symbol table. */
742- ecoffp -> stringsize = elfp -> stringsize ;
743- ecoffp -> stringtab = malloc (elfp -> stringsize );
744-
745- newstrings = (char * ) ecoffp -> stringtab ;
746- 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 );
747780 if (newstrings == NULL )
748781 errx (1 , "No memory for new string table" );
749- /* Copy and translate symbols... */
782+ /* Copy and translate symbols... */
783+ nsp = newstrings ;
750784 idx = 0 ;
751785 for (i = 0 ; i < nsyms ; i ++ ) {
752- int binding ;
753-
754- binding = ELF32_ST_BIND (( elfp -> elf_syms [ i ]. st_info )) ;
786+ const Elf32_Sym * esym = & elfp -> elf_syms [ i ] ;
787+ const char * name ;
788+ size_t namelen ;
755789
756- /* skip strange symbols */
757- if (binding == 0 ) {
790+ if (ELF32_ST_BIND (esym -> st_info ) == STB_LOCAL )
758791 continue ;
759- }
792+ name = oldstringbase + esym -> st_name ;
793+ namelen = strlen (name ) + 1 ;
794+ if (nsp + namelen > newstrings + stringsize )
795+ errx (1 , "ECOFF string table overflow" );
760796 /* Copy the symbol into the new table */
761- strcpy (nsp , oldstringbase + elfp -> elf_syms [ i ]. st_name );
797+ strcpy (nsp , name );
762798 ecoffp -> ecoff_syms [idx ].es_strindex = nsp - newstrings ;
763- nsp += strlen ( nsp ) + 1 ;
799+ nsp += namelen ;
764800
765801 /* translate symbol types to ECOFF XXX */
766802 ecoffp -> ecoff_syms [idx ].es_type = 1 ;
767803 ecoffp -> ecoff_syms [idx ].es_class = 5 ;
768804
769805 /* Symbol values in executables should be compatible. */
770- ecoffp -> ecoff_syms [idx ].es_value = elfp -> elf_syms [ i ]. st_value ;
806+ ecoffp -> ecoff_syms [idx ].es_value = esym -> st_value ;
771807 ecoffp -> ecoff_syms [idx ].es_symauxindex = 0xfffff ;
772808
773809 idx ++ ;
774810 }
775811
776812 ecoffp -> nsymbols = idx ;
813+ ecoffp -> stringtab = newstrings ;
777814 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 );
778819}
779820/*
780821 * pad to a 16-byte boundary
0 commit comments