#include <stdio.h>
#include <stdlib.h>
-#include <elf.h>
+#include "elf.h"
#define RELOCATABLE 0x1
#define EXECUTABLE 0x2
#define SYMLINKS 0x10
int readline(FILE *f, char *fn);
-int checkfile(char *fn, unsigned int want, int perr, int quiet);
+int checkfile(char *fn, unsigned int want, int perr);
int errors = 0;
int zeroterm = 0;
int main(int ac, char **av) {
int option;
unsigned int want = 0;
- int quiet = 0;
+ int printtype = 0;
+ int printname = 0;
+ int verbose = 0;
int perr = 0;
FILE *list = 0;
char fn[PATH_MAX];
- while ((option = getopt(ac, av, "redclaqp0f:")) != -1) {
+ while ((option = getopt(ac, av, "vtnredclap0f:")) != -1) {
switch (option) {
case 'r': want |= RELOCATABLE; break;
case 'e': want |= EXECUTABLE; break;
case 'c': want |= CORE; break;
case 'l': want |= SYMLINKS; break;
case 'a': want = (RELOCATABLE|EXECUTABLE|DYNAMIC|CORE); break;
- case 'q': quiet++; break;
+ case 't': printtype++; break;
+ case 'n': printname++; break;
+ case 'v': verbose++; break;
case 'p': perr++; break;
case '0': zeroterm = 1; break;
case 'f':
break;
}
}
+
+ if (!want) want = (RELOCATABLE|EXECUTABLE|DYNAMIC|CORE);
+
if (list) {
- quiet = 2;
+ int type;
perr = 0;
while (readline(list, fn)) {
- fprintf(stderr, "checking %s\n", fn);
- if (checkfile(fn, want,perr,quiet)) {
+ if ((type = checkfile(fn, want, perr)) & want) {
+ if (printtype) {
+ switch (type) {
+ case RELOCATABLE:
+ printf("relocatable "); break;
+ case EXECUTABLE:
+ printf("executable "); break;
+ case DYNAMIC:
+ printf("dynamic "); break;
+ case CORE:
+ printf("core "); break;
+ default:
+ printf("notelf "); break;
+ }
+ }
printf("%s\n", fn);
}
}
} else {
- fprintf(stderr, "checking %s\n", av[optind]);
- return !checkfile(av[optind], want,perr,quiet);
+ int type;
+ char *fn;
+
+ fn = av[optind];
+ if (verbose) fprintf(stderr, "checking %s\n", av[optind]);
+ type = checkfile(fn,want,perr);
+
+ if (printtype) {
+ switch (type) {
+ case RELOCATABLE:
+ printf("relocatable"); break;
+ case EXECUTABLE:
+ printf("executable"); break;
+ case DYNAMIC:
+ printf("dynamic"); break;
+ case CORE:
+ printf("core"); break;
+ default:
+ printf("notelf"); break;
+ }
+ }
+
+ if (printname) {
+ printf("%s%s", printtype ? " " : "", fn);
+ }
+ if (printtype || printname) printf("\n");
+
+ return type & want ? 0 : 1;
}
return errors ? 1 : 0;
}
return 0;
}
-int checkfile(char *fn, unsigned int want, int perr, int quiet) {
+int checkfile(char *fn, unsigned int want, int perr) {
Elf64_Ehdr hdr;
int fd, bytes;
int endian = 0;
return 0;
}
bytes = read(fd, &hdr, sizeof hdr);
- if (bytes < sizeof hdr) {
+ close(fd);
+ if ((size_t)bytes < sizeof hdr) {
if (perr) fprintf(stderr, "could not read full elf header (wanted %zu got %d bytes)\n", sizeof hdr, bytes);
- close(fd);
return 0;
}
if (hdr.e_ident[EI_MAG0] != ELFMAG0
|| hdr.e_ident[EI_MAG3] != ELFMAG3
) {
if (perr) fprintf(stderr, "elf header magic wrong\n");
- close(fd);
return 0;
}
switch (hdr.e_ident[EI_CLASS]) {
break;
default:
if (perr) fprintf(stderr, "elf header unknown class\n");
- close(fd);
return 0;
}
/* TODO swap endian if needed */
default:
if (perr) fprintf(stderr, "elf header unknown endian\n");
- close(fd);
return 0;
}
switch (hdr.e_type) {
- case ET_REL:
- if (!quiet) printf("relocatable\n");
- close(fd);
- return want & RELOCATABLE ? 1 : 0;
- case ET_EXEC:
- if (!quiet) printf("executable\n");
- close(fd);
- return want & EXECUTABLE ? 1 : 0;
- case ET_DYN:
- if (!quiet) printf("dynamic\n");
- close(fd);
- return want & DYNAMIC ? 1 : 0;
- case ET_CORE:
- if (!quiet) printf("core\n");
- close(fd);
- return want & CORE ? 1 : 0;
+ case ET_REL: return RELOCATABLE;
+ case ET_EXEC: return EXECUTABLE;
+ case ET_DYN: return DYNAMIC;
+ case ET_CORE: return CORE;
case ET_NONE:
default:
- if (perr) fprintf(stderr, "unknown type\n");
- close(fd);
+ if (perr) fprintf(stderr, "unknown %s\n", fn);
return 0;
}
- close(fd);
return 0;
}