From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17509 invoked by alias); 21 Jan 2004 23:08:13 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 17496 invoked from network); 21 Jan 2004 23:08:10 -0000 Received: from unknown (HELO walton.kettenis.dyndns.org) (213.93.115.144) by sources.redhat.com with SMTP; 21 Jan 2004 23:08:10 -0000 Received: from elgar.kettenis.dyndns.org (elgar.kettenis.dyndns.org [192.168.0.2]) by walton.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i0LN899e000354 for ; Thu, 22 Jan 2004 00:08:09 +0100 (CET) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: from elgar.kettenis.dyndns.org (localhost [127.0.0.1]) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6) with ESMTP id i0LN89Sm014523 for ; Thu, 22 Jan 2004 00:08:09 +0100 (CET) (envelope-from kettenis@elgar.kettenis.dyndns.org) Received: (from kettenis@localhost) by elgar.kettenis.dyndns.org (8.12.6p3/8.12.6/Submit) id i0LN89Fb014520; Thu, 22 Jan 2004 00:08:09 +0100 (CET) Date: Wed, 21 Jan 2004 23:08:00 -0000 Message-Id: <200401212308.i0LN89Fb014520@elgar.kettenis.dyndns.org> From: Mark Kettenis To: gdb-patches@sources.redhat.com In-reply-to: <20040119185317.GA20236@nevyn.them.org> (message from Daniel Jacobowitz on Mon, 19 Jan 2004 13:53:17 -0500) Subject: Re: [PATCH/RFC] Reorganize osabi.c:generic_elf_osabi_sniff_abi_tag_sections() References: <200401182040.i0IKeeMu008703@elgar.kettenis.dyndns.org> <20040118225254.GA8516@nevyn.them.org> <200401191839.i0JId3oh000527@elgar.kettenis.dyndns.org> <20040119185317.GA20236@nevyn.them.org> X-SW-Source: 2004-01/txt/msg00601.txt.bz2 Daniel's confusement (can I say that in english?) caused me to tweak some comments. The attached is what I committed. Mark Index: ChangeLog from Mark Kettenis * osabi.c (MAX_NOTESZ): New define. (check_note): New function. (generic_elf_osabi_sniff_abi_tag_sections): Reorganize code using check_note. Index: osabi.c =================================================================== RCS file: /cvs/src/src/gdb/osabi.c,v retrieving revision 1.25 diff -u -p -r1.25 osabi.c --- osabi.c 17 Jan 2004 00:13:46 -0000 1.25 +++ osabi.c 21 Jan 2004 23:02:22 -0000 @@ -355,119 +355,128 @@ gdbarch_init_osabi (struct gdbarch_info info.bfd_arch_info->printable_name); } +/* Limit on the amount of data to be read. */ +#define MAX_NOTESZ 128 + +/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ + +static int +check_note (bfd *abfd, asection *sect, const char *note, + const char *name, unsigned long descsz, unsigned long type) +{ + unsigned long notesz; + + /* Calculate the size of this note. */ + notesz = strlen (name) + 1; + notesz = ((notesz + 3) & ~3); + notesz += descsz; + notesz = ((notesz + 3) & ~3); + + /* If this assertion triggers, increase MAX_NOTESZ. */ + gdb_assert (notesz <= MAX_NOTESZ); + + /* Check whether SECT is big enough to comtain the complete note. */ + if (notesz > bfd_section_size (abfd, sect)) + return 0; + + /* Check the note name. */ + if (bfd_h_get_32 (abfd, note) != (strlen (name) + 1) + || strcmp (note + 12, name) != 0) + return 0; + + /* Check the descriptor size. */ + if (bfd_h_get_32 (abfd, note + 4) != descsz) + return 0; + + /* Check the note type. */ + if (bfd_h_get_32 (abfd, note + 8) != type) + return 0; + + return 1; +} /* Generic sniffer for ELF flavoured files. */ void generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) { - enum gdb_osabi *os_ident_ptr = obj; + enum gdb_osabi *osabi = obj; const char *name; unsigned int sectsize; + char *note; name = bfd_get_section_name (abfd, sect); sectsize = bfd_section_size (abfd, sect); - /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ - if (strcmp (name, ".note.ABI-tag") == 0 && sectsize > 0) - { - unsigned int name_length, data_length, note_type; - char *note; + /* Limit the amount of data to read. */ + if (sectsize > MAX_NOTESZ) + sectsize = MAX_NOTESZ; - /* If the section is larger than this, it's probably not what we are - looking for. */ - if (sectsize > 128) - sectsize = 128; + note = alloca (sectsize); + bfd_get_section_contents (abfd, sect, note, 0, sectsize); - note = alloca (sectsize); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sectsize); - - name_length = bfd_h_get_32 (abfd, note); - data_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 4 && data_length == 16 && note_type == NT_GNU_ABI_TAG - && strcmp (note + 12, "GNU") == 0) + /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ + if (strcmp (name, ".note.ABI-tag") == 0) + { + /* GNU. */ + if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG)) { - int os_number = bfd_h_get_32 (abfd, note + 16); + unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16); - switch (os_number) + switch (abi_tag) { case GNU_ABI_TAG_LINUX: - *os_ident_ptr = GDB_OSABI_LINUX; + *osabi = GDB_OSABI_LINUX; break; case GNU_ABI_TAG_HURD: - *os_ident_ptr = GDB_OSABI_HURD; + *osabi = GDB_OSABI_HURD; break; case GNU_ABI_TAG_SOLARIS: - *os_ident_ptr = GDB_OSABI_SOLARIS; + *osabi = GDB_OSABI_SOLARIS; break; case GNU_ABI_TAG_FREEBSD: - *os_ident_ptr = GDB_OSABI_FREEBSD_ELF; + *osabi = GDB_OSABI_FREEBSD_ELF; break; - + case GNU_ABI_TAG_NETBSD: - *os_ident_ptr = GDB_OSABI_NETBSD_ELF; + *osabi = GDB_OSABI_NETBSD_ELF; break; - + default: - internal_error - (__FILE__, __LINE__, - "generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d", - os_number); + internal_error (__FILE__, __LINE__, "\ +generic_elf_osabi_sniff_abi_tag_sections: unknown OS number %d", + abi_tag); } return; } - else if (name_length == 8 && data_length == 4 - && note_type == NT_FREEBSD_ABI_TAG - && strcmp (note + 12, "FreeBSD") == 0) + + /* FreeBSD. */ + if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG)) { - /* XXX Should we check the version here? Probably not - necessary yet. */ - *os_ident_ptr = GDB_OSABI_FREEBSD_ELF; + /* There is no need to check the version yet. */ + *osabi = GDB_OSABI_FREEBSD_ELF; + return; } + return; } - + /* .note.netbsd.ident notes, used by NetBSD. */ - if (strcmp (name, ".note.netbsd.ident") == 0 && sectsize > 0) + if (strcmp (name, ".note.netbsd.ident") == 0 + && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT)) { - unsigned int name_length, data_length, note_type; - char *note; - - /* If the section is larger than this, it's probably not what we are - looking for. */ - if (sectsize > 128) - sectsize = 128; - - note = alloca (sectsize); - - bfd_get_section_contents (abfd, sect, note, - (file_ptr) 0, (bfd_size_type) sectsize); - - name_length = bfd_h_get_32 (abfd, note); - data_length = bfd_h_get_32 (abfd, note + 4); - note_type = bfd_h_get_32 (abfd, note + 8); - - if (name_length == 7 && data_length == 4 && note_type == NT_NETBSD_IDENT - && strcmp (note + 12, "NetBSD") == 0) - { - /* XXX Should we check the version here? Probably not - necessary yet. */ - *os_ident_ptr = GDB_OSABI_NETBSD_ELF; - } + /* There is no need to check the version yet. */ + *osabi = GDB_OSABI_NETBSD_ELF; return; } /* .note.netbsdcore.procinfo notes, used by NetBSD. */ - if (strcmp (name, ".note.netbsdcore.procinfo") == 0 && sectsize > 0) + if (strcmp (name, ".note.netbsdcore.procinfo") == 0) { - *os_ident_ptr = GDB_OSABI_NETBSD_ELF; + *osabi = GDB_OSABI_NETBSD_ELF; return; } }