#ifndef READELF #include "ft_nm.h" #define LAUNCH32 ft_nm32(filename, buf.st_size, file, parse_opts(argc, argv)) #define LAUNCH64 ft_nm64(filename, buf.st_size, file, parse_opts(argc, argv)) #else #include "ft_re.h" #define LAUNCH32 ft_re32(filename, buf.st_size, file, parse_opts(argc, argv)) #define LAUNCH64 ft_re64(filename, buf.st_size, file, parse_opts(argc, argv)) #endif int is_ignored(char c) { return (c == '_' || c == '.' || c == '/' || c == '@' || c == '<' || c == '-' || c == '>'); } int strcmp_ignored(char *s1, char *s2) { char *s1_cpy = s1; char *s2_cpy = s2; while (*s1 && *s2) { while (*s1 && is_ignored(*s1)) s1++; while (*s2 && is_ignored(*s2)) s2++; if (toupper(*s1) != toupper(*s2)) return (toupper(*s1) - toupper(*s2)); if (*s1) s1++; if (*s2) s2++; } if (*s1) return toupper(*s1); else if (*s2) return -toupper(*s2); else return strcmp(s1_cpy, s2_cpy); } t_elf_opts parse_opts(int argc, char **argv) { t_elf_opts opts = {0}; for (int i = 0; i < argc; ++i) { if (argv[i][0] != '-') continue; for (int j = 0; argv[i][j]; ++j) { if (argv[i][j] == 'a') opts.a = 1; else if (argv[i][j] == 'g') opts.g = 1; else if (argv[i][j] == 'u') opts.u = 1; else if (argv[i][j] == 'r') opts.r = 1; else if (argv[i][j] == 'p') opts.p = 1; else if (argv[i][j] == 'D') opts.D = 1; } } return opts; } int get_filename_pos(char **argv) { int i = 1; while (argv[i] && argv[i][0] == '-') i++; return argv[i] ? i : 0; } int is_valid_file(char *file) { return file[EI_MAG0] == ELFMAG0 && file[EI_MAG1] == ELFMAG1 && file[EI_MAG2] == ELFMAG2 && file[EI_MAG3] == ELFMAG3 && (file[EI_CLASS] == ELFCLASS32 || file[EI_CLASS] == ELFCLASS64) && (file[EI_DATA] == ELFDATA2LSB || file[EI_DATA] == ELFDATA2MSB) && (file[EI_VERSION] == EV_CURRENT) && (file[16] == ET_REL || file[16] == ET_EXEC || file[16] == ET_DYN) && (file[18] == EM_386 || file[18] == 6 || file[18] == EM_X86_64); } int main(int argc, char **argv) { int fd; struct stat buf; char *file; int file_id = get_filename_pos(argv); char *filename = file_id == 0 ? "a.out" : argv[file_id]; int ret = -1; if ((fd = open(filename, O_RDONLY)) < 0) return (perror("open"), EXIT_FAILURE); if (fstat(fd, &buf) < 0) return (perror("fstat"), EXIT_FAILURE); if (S_ISDIR(buf.st_mode)) return (ft_fprintf(stderr, "nm: Attention : « %s » est un répertoire\n", filename), EXIT_FAILURE); file = mmap(NULL, buf.st_size, PROT_READ, MAP_PRIVATE, fd, 0); if (is_valid_file(file)) { if (file[EI_CLASS] == ELFCLASS32) ret = LAUNCH32; else if (file[EI_CLASS] == ELFCLASS64) ret = LAUNCH64; else ret = -1; } else ret = -1; // printf("%d %d %d %d %d %d %d %d %d %d %d %d %d", file[8], file[9], file[10], file[11], // file[12], file[13], file[14], file[15], file[16], file[17], file[18], file[19], file[20]); if (ret == -3) ft_fprintf(stderr, "bfd plugin: %s: file too short\n", filename); if (ret == -1 || ret == -3) ft_fprintf(stderr, "nm: %s: format de fichier non reconnu\n", filename); if (ret == -2) ft_fprintf(stderr, "nm: %s: aucun symbole\n", filename); if (munmap(file, buf.st_size) < 0) return (perror("munmap"), EXIT_FAILURE); return (close(fd), EXIT_SUCCESS); }