Skip to content

Commit 9ca5acb

Browse files
Pull up following revision(s) (requested by tsutsui in ticket #1968):
usr.bin/elf2ecoff/elf2ecoff.c: revision 1.34 usr.bin/elf2ecoff/elf2ecoff.c: revision 1.35 usr.bin/elf2ecoff/elf2ecoff.c: revision 1.36 usr.bin/elf2ecoff/elf2ecoff.c: revision 1.37 usr.bin/elf2ecoff/elf2ecoff.c: revision 1.38 fix few typos in comments and log messages. s/sharable/shareable in comments and documentation. Revert "debug" variable to global to override it on debugger etc. elf2ecoff: fix PR port-pmax/59234: "buffer overflow detected" problem. Explicitly calculate a size of the target ECOFF string table before copying symbol strings, as suggested by mlelstv@. Tested "build.sh -U -m pmax release" on ubuntu 24.04.2: --- % ./nbmips-elf2ecoff netboot.elf netboot combining PH 0 type 1 flags 0x7 with data, ndata = 73568, nbss =1392 skipping PH 1 type 0x70000000 flags 0x4 skipping PH 2 type 0x70000003 flags 0x4 wrote 20 byte file header. wrote 56 byte a.out header. wrote 240 bytes of section headers. wrote 4 byte pad. writing 73568 bytes... writing syms at offset 0x12100 2605 (0xa2d) bytes ELF string table 2705 (0xa91) bytes required for ECOFF string table 2705 (0xa91) bytes used for ECOFF string table writing symhdr for 258 entries at offset 0x120a0 ECOFF symhdr: symhdr 60, strsize a91, symsize 1020 --- s/estimate/compute/
1 parent cb215b1 commit 9ca5acb

1 file changed

Lines changed: 64 additions & 23 deletions

File tree

usr.bin/elf2ecoff/elf2ecoff.c

Lines changed: 64 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
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+
7879
static int needswap;
7980

8081
static int phcmp(Elf32_Phdr *, Elf32_Phdr *);
8182
static char *saveRead(int, off_t, off_t, const char *);
8283
static void safewrite(int, const void *, off_t, const char *);
8384
static void copy(int, int, off_t, off_t);
8485
static 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);
8588
static void translate_syms(struct elf_syms *, struct ecoff_syms *);
8689
static 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
*/
722750
static void
723751
translate_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

Comments
 (0)