Subject: Why mark our .note.netbsd signature LOADable?
To: None <tech-toolchain@NetBSD.org>
From: Martin Husemann <martin@duskware.de>
List: tech-toolchain
Date: 12/06/2006 14:44:44
--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
After playing with .note sections to mark the kernel as a NetBSD binary
yesterday, I commited a change to the .note section generating code
for the kernel. At this time I was a bit confused, and did not fully
understand what this caused.
When thinking about it later, I wondered if we should do the same change to
the userland .note section. A patch that does this, and also changes
exec_elf32.c to cope with it is attached.
I am not sure we want to do this - so let me try to explain the change:
What is the difference?
Our current note mark is a PT_NOTE PHDR:
NOTE off 0x00000000000001a4 vaddr 0x00000000001001a4 paddr 0x00000000001001a4 align 2**2
filesz 0x0000000000000018 memsz 0x0000000000000018 flags r--
It creates a SHT_NOTE section too:
1 .note.netbsd.ident 00000018 00000000001001a4 00000000001001a4 000001a4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
Since this note is only used to mark our binaries, it is something that is not
needed after starting the binary, so for one the LOAD flag is not needed, IMHO.
Neither is the ALLOC or DATA.
So, with the same change I did to the kernel note section done to userland,
this all ends up without a PT_NOTE phdr, but only a simple SHT_NOTE section:
# objdump -p /bin/ls
/bin/ls: file format elf64-sparc
Program Header:
PHDR off 0x0000000000000040 vaddr 0x0000000000100040 paddr 0x0000000000100040 align 2**3
filesz 0x0000000000000118 memsz 0x0000000000000118 flags r-x
INTERP off 0x0000000000000158 vaddr 0x0000000000100158 paddr 0x0000000000100158 align 2**0
filesz 0x0000000000000013 memsz 0x0000000000000013 flags r--
LOAD off 0x0000000000000000 vaddr 0x0000000000100000 paddr 0x0000000000100000 align 2**20
filesz 0x0000000000004fe4 memsz 0x0000000000004fe4 flags r-x
LOAD off 0x0000000000004fe8 vaddr 0x0000000000204fe8 paddr 0x0000000000204fe8 align 2**20
filesz 0x00000000000009d4 memsz 0x0000000000000d20 flags rwx
DYNAMIC off 0x0000000000005010 vaddr 0x0000000000205010 paddr 0x0000000000205010 align 2**3
filesz 0x0000000000000190 memsz 0x0000000000000190 flags rw-
Dynamic Section:
NEEDED libc.so.12
RPATH /lib
INIT 0x101130
FINI 0x104d40
HASH 0x100170
STRTAB 0x100948
SYMTAB 0x100318
STRSZ 0x260
SYMENT 0x18
DEBUG 0x0
PLTGOT 0x205300
PLTRELSZ 0x480
PLTREL 0x7
JMPREL 0x100cb0
RELA 0x100ba8
RELASZ 0x588
RELAENT 0x18
0x70000001 0x1
0x70000001 0x2
and still a SHT_NOTE section:
# objdump -h /bin/ls
/bin/ls: file format elf64-sparc
Sections:
Idx Name Size VMA LMA File off Algn
[...]
21 .note.netbsd.ident 00000018 0000000000000000 0000000000000000 00005df0 2**2
CONTENTS, READONLY
a slightly older file(1) is still happy with this (-current file(1) looks
broken again, but that is probably unrelated), and gdb seems to be fine
too:
# gdb
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "sparc64--netbsd".
(gdb) set debug arch 1
(gdb) file /bin/ls
find_arch_by_info: info.bfd_arch_info sparc:v9
find_arch_by_info: info.byte_order 0 (big)
find_arch_by_info: info.osabi 9 (NetBSD ELF)
find_arch_by_info: info.abfd 0x4f2c00
find_arch_by_info: info.tdep_info 0x0
... but then I can't test gdb for real, because currently PTRACE seems to
be broken.
Do we want this change?
Martin
--NzB8fVQJ5HfG6fxh
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch
Index: libexec/ld.elf_so/sysident.h
===================================================================
RCS file: /cvsroot/src/libexec/ld.elf_so/sysident.h,v
retrieving revision 1.13
diff -u -p -r1.13 sysident.h
--- libexec/ld.elf_so/sysident.h 13 Jun 2006 13:55:58 -0000 1.13
+++ libexec/ld.elf_so/sysident.h 6 Dec 2006 13:24:41 -0000
@@ -63,7 +63,7 @@
#define __S(x) __STRING(x)
__asm(
- ".section\t\".note.netbsd.ident\", \"a\"\n"
+ ".section\t\".note.netbsd.ident\", \"\",@note\n"
"\t.p2align\t2\n\n"
"\t.long\t" __S(ELF_NOTE_NETBSD_NAMESZ) "\n"
Index: sys/kern/exec_elf32.c
===================================================================
RCS file: /cvsroot/src/sys/kern/exec_elf32.c,v
retrieving revision 1.120
diff -u -p -r1.120 exec_elf32.c
--- sys/kern/exec_elf32.c 24 Nov 2006 01:13:11 -0000 1.120
+++ sys/kern/exec_elf32.c 6 Dec 2006 13:24:41 -0000
@@ -119,6 +119,7 @@ int netbsd_elf_probe(struct lwp *, struc
#define ELF_TRUNC(a, b) ((a) & ~((b) - 1))
#define MAXPHNUM 50
+#define MAXSHNUM 1000
/*
* Copy arguments onto the stack in the normal way, but add some
@@ -761,11 +762,13 @@ netbsd_elf_signature(struct lwp *l, stru
Elf_Ehdr *eh)
{
size_t i;
- Elf_Phdr *ph;
- size_t phsize;
+ Elf_Phdr *ph = NULL;
+ Elf_Shdr *sh = NULL;
+ Elf_Nhdr *np = NULL;
+ size_t phsize, shsize;
int error;
- if (eh->e_phnum > MAXPHNUM)
+ if (eh->e_phnum > MAXPHNUM || eh->e_shnum > MAXSHNUM)
return ENOEXEC;
phsize = eh->e_phnum * sizeof(Elf_Phdr);
@@ -773,10 +776,43 @@ netbsd_elf_signature(struct lwp *l, stru
error = exec_read_from(l, epp->ep_vp, eh->e_phoff, ph, phsize);
if (error)
goto out;
+ shsize = eh->e_shnum * sizeof(Elf_Shdr);
+ sh = (Elf_Shdr *)malloc(shsize, M_TEMP, M_WAITOK);
+ error = exec_read_from(l, epp->ep_vp, eh->e_shoff, sh, shsize);
+ if (error)
+ goto out;
+
+ for (i = 0; i < eh->e_shnum; i++) {
+ Elf_Shdr *shp = &sh[i];
+
+ if (shp->sh_type != SHT_NOTE ||
+ shp->sh_size > 1024 ||
+ shp->sh_size < sizeof(Elf_Nhdr) + ELF_NOTE_NETBSD_NAMESZ)
+ continue;
+
+ np = (Elf_Nhdr *)malloc(shp->sh_size, M_TEMP, M_WAITOK);
+ error = exec_read_from(l, epp->ep_vp, shp->sh_offset, np,
+ shp->sh_size);
+ if (error)
+ goto next1;
+ if (np->n_type != ELF_NOTE_TYPE_NETBSD_TAG ||
+ np->n_namesz != ELF_NOTE_NETBSD_NAMESZ ||
+ np->n_descsz != ELF_NOTE_NETBSD_DESCSZ ||
+ memcmp((caddr_t)(np + 1), ELF_NOTE_NETBSD_NAME,
+ ELF_NOTE_NETBSD_NAMESZ))
+ goto next1;
+
+ error = 0;
+ free(np, M_TEMP);
+ goto out;
+
+ next1:
+ free(np, M_TEMP);
+ continue;
+ }
for (i = 0; i < eh->e_phnum; i++) {
Elf_Phdr *ephp = &ph[i];
- Elf_Nhdr *np;
if (ephp->p_type != PT_NOTE ||
ephp->p_filesz > 1024 ||
@@ -787,27 +823,28 @@ netbsd_elf_signature(struct lwp *l, stru
error = exec_read_from(l, epp->ep_vp, ephp->p_offset, np,
ephp->p_filesz);
if (error)
- goto next;
+ goto next2;
if (np->n_type != ELF_NOTE_TYPE_NETBSD_TAG ||
np->n_namesz != ELF_NOTE_NETBSD_NAMESZ ||
np->n_descsz != ELF_NOTE_NETBSD_DESCSZ ||
memcmp((caddr_t)(np + 1), ELF_NOTE_NETBSD_NAME,
ELF_NOTE_NETBSD_NAMESZ))
- goto next;
+ goto next2;
error = 0;
free(np, M_TEMP);
goto out;
- next:
+ next2:
free(np, M_TEMP);
continue;
}
error = ENOEXEC;
out:
- free(ph, M_TEMP);
+ if (ph) free(ph, M_TEMP);
+ if (sh) free(sh, M_TEMP);
return error;
}
--NzB8fVQJ5HfG6fxh--