Re: NetBSD/ews4800mips 9.0 on NEC EWS4800/360AD

Izumi Tsutsui <[email protected]>
Newsgroups gmane.os.netbsd.ports.mips.devel
Message-ID <[email protected]>
I wrote:

> Note there is something wrong in bootloader (/usr/mdec/boot)
> binary so it gets "Illegal exception" error just after it's loaded
> by the primary bootxx_bfs.  An old /usr/mdec/boot binary from
> NetBSD/ews4800mips 5.0 still works.

It turns out that the primary bootxx_bfs binary doesn't load the
secondary boot built by recent toolchain.

In sys/arch/ews4800mips/stand/common/bootxx.c, load_elf() just
loads the first two problem header sections:
---
int
load_elf(uint8_t *buf, uint32_t *entry)
{
	Elf32_Ehdr *e = (void *)buf;
	Elf32_Phdr *p;
[..]
	BASSERT(e->e_phentsize == sizeof(Elf32_Phdr));
	p = (void *)(buf + e->e_phoff);
#ifdef _STANDALONE
	memcpy((void *)p->p_vaddr, buf + p->p_offset, p->p_filesz);
	p++;
	memcpy((void *)p->p_vaddr, buf + p->p_offset, p->p_filesz);
#else
---

but recent gcc/binutils seem to create three sections.

5.0 /usr/mdec/boot (by readelf -a):
---
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  REGINFO        0x014c18 0xa0a14b98 0xa0a14b98 0x00018 0x00018 R   0x4
  LOAD           0x000080 0xa0a00000 0xa0a00000 0x14e60 0x1a538 RWE 0x40
---

9.0 /usr/mdec/boot:
---
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  ABIFLAGS       0x015088 0xa0a14fc8 0xa0a14fc8 0x00018 0x00018 R   0x8
  REGINFO        0x015070 0xa0a14fb0 0xa0a14fb0 0x00018 0x00018 R   0x4
  LOAD           0x0000c0 0xa0a00000 0xa0a00000 0x15280 0x1a978 RWE 0x40
---

It works to change bootxx.c to check all sections in the problem header
as MI libsa loadfile_elf32.c does:

---
Index: common/bootxx.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ews4800mips/stand/common/bootxx.c,v
retrieving revision 1.5
diff -u -p -d -r1.5 bootxx.c
--- common/bootxx.c	4 Feb 2009 15:22:13 -0000	1.5
+++ common/bootxx.c	6 Jun 2020 18:11:54 -0000
@@ -46,6 +46,10 @@
 
 #include "common.h"
 
+#define	IS_TEXT(p)	(p.p_flags & PF_X)
+#define	IS_DATA(p)	((p.p_flags & PF_X) == 0)
+#define	IS_BSS(p)	(p.p_filesz < p.p_memsz)
+
 #define	FILHSZ	(sizeof(struct ecoff_filehdr))
 #define	SCNHSZ	(sizeof(struct ecoff_scnhdr))
 #define	N_TXTOFF(f, a)							\
@@ -186,6 +190,7 @@ load_elf(uint8_t *buf, uint32_t *entry)
 {
 	Elf32_Ehdr *e = (void *)buf;
 	Elf32_Phdr *p;
+	int i;
 
 	if (e->e_ident[EI_MAG2] != 'L' || e->e_ident[EI_MAG3] != 'F' ||
 	    e->e_ident[EI_CLASS] != ELFCLASS32 ||
@@ -197,16 +202,39 @@ load_elf(uint8_t *buf, uint32_t *entry)
 	BASSERT(e->e_phentsize == sizeof(Elf32_Phdr));
 	p = (void *)(buf + e->e_phoff);
 #ifdef _STANDALONE
-	memcpy((void *)p->p_vaddr, buf + p->p_offset, p->p_filesz);
-	p++;
-	memcpy((void *)p->p_vaddr, buf + p->p_offset, p->p_filesz);
+	for (i = 0; i < e->e_phnum; i++) {
+		if (p[i].p_type != PT_LOAD ||
+		    (p[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
+			continue;
+		if (IS_TEXT(p[i]) || IS_DATA(p[i])) {
+			memcpy((void *)p[i].p_vaddr,
+			    buf + p[i].p_offset, p[i].p_filesz);
+		}
+		if (IS_BSS(p[i])) {
+			memset((void *)(p[i].p_vaddr + p[i].p_filesz), 0,
+			    p[i].p_memsz - p[i].p_filesz);
+		}
+	}
 #else
 	DPRINTF("ELF entry point 0x%08x\n", e->e_entry);
-	DPRINTF("[text] 0x%08x 0x%x %dbyte.\n", p->p_vaddr, p->p_offset,
-	    p->p_filesz);
-	p++;
-	DPRINTF("[data] 0x%08x 0x%x %dbyte.\n", p->p_vaddr, p->p_offset,
-	    p->p_filesz);
+	for (i = 0; i < e->e_phnum; i++) {
+		if (p[i].p_type != PT_LOAD ||
+		    (p[i].p_flags & (PF_W|PF_R|PF_X)) == 0)
+			continue;
+		if (IS_TEXT(p[i])) {
+			DPRINTF("[text] 0x%08x 0x%x %dbyte.\n",
+			    p[i].p_vaddr, p[i].p_offset, p[i].p_filesz);
+		}
+		if (IS_DATA(p[i])) {
+			DPRINTF("[data] 0x%08x 0x%x %dbyte.\n",
+			    p[i].p_vaddr, p[i].p_offset, p[i].p_filesz);
+		}
+		if (IS_BSS(p[i])) {
+			DPRINTF("[bss] 0x%08x %dbyte.\n",
+			    p[i].p_vaddr + p[i].p_filesz,
+			    p[i].p_memsz - p[i].p_filesz);
+		}
+	}
 #endif
 	*entry = e->e_entry;
 
---

I'll commit fix and send a pullup request to netbsd-9.

---
Izumi Tsutsui
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.