You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
90 lines
3.5 KiB
90 lines
3.5 KiB
#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);
|
|
}
|
|
|