From Mitch.Dsouza@Dubai.Sun.COM Fri Jun 16 16:02:36 1995 Date: Fri, 16 Jun 1995 19:09:14 +0400 From: Mitch.Dsouza@Dubai.Sun.COM (Mitch DSouza) To: daniel.barlow@st-johns.oxford.ac.uk Subject: New file.c patch X-Sun-Charset: US-ASCII Content-Length: 3109 [...] *** file.c.orig Tue Mar 7 19:12:13 1995 --- file.c Wed Jun 14 03:08:02 1995 *************** *** 42,52 **** #include #endif #include /* for read() */ ! #include "patchlevel.h" #include "file.h" #ifdef S_IFLNK # define USAGE "Usage: %s [-vczL] [-f namefile] [-m magicfile] file...\n" #else # define USAGE "Usage: %s [-vcz] [-f namefile] [-m magicfile] file...\n" --- 42,63 ---- #include #endif #include /* for read() */ ! #ifdef HAVE_ELF ! #include ! static void swapbytes(char *p, int len) { ! char c, i; ! for (i=0; i<(len>>1); i++) { ! c=p[i]; ! p[i]=p[len-i-1]; ! p[len-i-1]=c; ! } ! } ! #endif #include "patchlevel.h" #include "file.h" #ifdef S_IFLNK + # define USAGE "Usage: %s [-vczL] [-f namefile] [-m magicfile] file...\n" #else # define USAGE "Usage: %s [-vcz] [-f namefile] [-m magicfile] file...\n" *************** *** 258,263 **** --- 269,339 ---- tryit(buf, nbytes, zflag); } + #ifdef HAVE_ELF + /* + * ELF can have an arbitrary number of sections and thus file(1) + * cannot use a fixed position in the file to determine its type. + * Instead we must traverse all sections to see if one is a symbol + * table section. + */ + + if (nbytes > sizeof(Elf32_Ehdr) && + buf[EI_MAG0] == ELFMAG0 && + buf[EI_MAG1] == ELFMAG1 && + buf[EI_MAG2] == ELFMAG2 && + buf[EI_MAG3] == ELFMAG3) { + Elf32_Ehdr elfhdr; + int stripped = 1, dynamic = 0, crossendian = 0; + + (void) memcpy (&elfhdr, buf, sizeof (Elf32_Ehdr)); + + /* + * Little Endian Host: (char *)&stripped[0] == 1 + * Big Endian Host: (char *)&stripped[0] == 0 + */ + + if ((((char *)&stripped)[0]==1 && buf[EI_DATA]==ELFDATA2MSB) || + (((char *)&stripped)[0]==0 && buf[EI_DATA]==ELFDATA2LSB)) { + + crossendian = 1; + + swapbytes((char *)&elfhdr.e_shoff, + sizeof elfhdr.e_shoff); + + swapbytes((char *)&elfhdr.e_shnum, + sizeof elfhdr.e_shnum); + + swapbytes((char *)&elfhdr.e_shentsize, + sizeof elfhdr.e_shentsize); + } + + if (lseek(fd, elfhdr.e_shoff, SEEK_SET)<0) + error("seek failed (%s).\n", strerror(errno)); + + for (;elfhdr.e_shnum;elfhdr.e_shnum--) { + if (read(fd, (char *)buf, elfhdr.e_shentsize)<0) + error("read failed (%s).\n", strerror(errno)); + + if (crossendian) + swapbytes((char *)&((Elf32_Shdr *)buf)->sh_type, + sizeof (((Elf32_Shdr *)buf)->sh_type)); + + if (((Elf32_Shdr *)buf)->sh_type==SHT_SYMTAB) + stripped = 0; + + if (((Elf32_Shdr *)buf)->sh_type==SHT_DYNAMIC) + dynamic = 1; + } + if (dynamic) + (void) printf(", dynamically"); + else + (void) printf(", statically"); + (void) printf(" linked, "); + if (!stripped) + (void) printf("not "); + (void) printf("stripped"); + } + #endif if (inname != stdname) { /* * Try to restore access, modification times if read it.