My own elf programs.
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

#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);
}