diff --git a/Makefile b/Makefile index 3ee259d..588a1b7 100644 --- a/Makefile +++ b/Makefile @@ -4,6 +4,9 @@ SRC_FILES = main.c \ error.c \ header.c \ ident.c \ + nm.c \ + fetch.c \ + ft_printf.c \ INC_FILES = ft_nm.h \ diff --git a/inc/ft_nm.h b/inc/ft_nm.h index 7c20407..277c925 100644 --- a/inc/ft_nm.h +++ b/inc/ft_nm.h @@ -4,17 +4,31 @@ # include # include # include -# include # include +# include +# include +# include +# include # include "libft.h" # define FT_NM_SUCCESS 0 # define FT_NM_FAILURE -1 +typedef struct s_mapped_file { + void *ptr; + off_t size; +} t_mapped_file; + +void ft_printf(const char *format, ...); void ft_nm_error(const char *path); + int check_header(Elf64_Ehdr *header); int check_ident(unsigned char ident[EI_NIDENT]); +void *fetch(t_mapped_file mapped_file, size_t offset, size_t fetch_size); + +void nm32(t_mapped_file mapped_file); +void nm64(t_mapped_file mapped_file); #endif diff --git a/src/fetch.c b/src/fetch.c new file mode 100644 index 0000000..cbb7652 --- /dev/null +++ b/src/fetch.c @@ -0,0 +1,8 @@ +#include "ft_nm.h" + +void *fetch(t_mapped_file mapped_file, size_t offset, size_t fetch_size) { + if (offset + (size_t)fetch_size <= (size_t)mapped_file.size) { + return mapped_file.ptr + offset; + } + return NULL; +} diff --git a/src/ft_printf.c b/src/ft_printf.c new file mode 100644 index 0000000..8e1d847 --- /dev/null +++ b/src/ft_printf.c @@ -0,0 +1,54 @@ +#include "ft_nm.h" + +void ft_print_hex_digit(char c) { + if (c > 9) { + ft_putchar(c + 'W'); + } else { + ft_putchar(c + '0'); + } +} + +void ft_put_address_32(uint32_t addr) { + for (char i = 7; i >= 0; i--) { + ft_print_hex_digit((addr >> i) & 0xF); + } +} + +void ft_put_address_64(uint64_t addr) { + for (char i = 15; i >= 0; i--) { + ft_print_hex_digit((addr >> i) & 0xF); + } +} + +void ft_printf(const char *format, ...) { + va_list ap; + int argc = ft_strlen(format); + + va_start(ap, format); + for (int i = 0; i < argc; i++) { + switch (format[i]) { + case 's': + ft_putstr(va_arg(ap, char *)); + break; + case 'd': + ft_putnbr(va_arg(ap, int)); + break; + case 'x': + ft_put_address_32(va_arg(ap, uint32_t)); + break; + case 'X': + ft_put_address_64(va_arg(ap, uint64_t)); + break; + case ' ': + ft_putchar(' '); + break; + case 'p': + ft_putstr(" "); + break; + case 'P': + ft_putstr(" "); + break; + } + } + va_end(ap); +} diff --git a/src/main.c b/src/main.c index 5eda71b..81dfe27 100644 --- a/src/main.c +++ b/src/main.c @@ -1,47 +1,55 @@ #include "ft_nm.h" -void print_bits(char c) { - for (int a = 7; a >= 0; a--) { - ft_putnbr(c >> a & 1); - } - ft_putchar('\n'); -} - int main(int ac, char **av) { char *path = ft_strdup("a.out"); + bool path_allocated = true; + if (ac > 1) { free(path); + path_allocated = false; path = av[1]; } + int fd = open(path, O_RDONLY); if (fd == -1) { ft_nm_error(path); } - void *ptr = NULL; -// Elf64_Ehdr *header; - unsigned char ident[EI_NIDENT]; - ptr = mmap(NULL, 64, PROT_READ, MAP_PRIVATE, fd, 0); - if (ptr != MAP_FAILED) { - ft_memcpy(ident, ptr, EI_NIDENT); - //header = (Elf64_Ehdr *)ptr; - if (check_ident(ident) == FT_NM_FAILURE) { - printf("ft_nm: %s: file format not recognized\n", path); - exit (1); - } - for (int i = 0; i < 16; i++) { - print_bits(((char *)ptr)[i]); - } -/* if (header->e_ident[EI_OSABI] == 0x00) { - printf("This ELF is for System V! :)\n"); - } - else if (header->e_ident[EI_OSABI] == 0x03) { - printf("This ELF is for linux! :)\n"); - } else { - printf("What's my purpose :(\n"); - } - */ + + struct stat stat; + if (fstat(fd, &stat) == -1) { + ft_nm_error(path); } + t_mapped_file mapped_file; + + ft_printf("sds", "file size: ", stat.st_size, "\n"); + mapped_file.ptr = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + mapped_file.size = stat.st_size; + if (mapped_file.ptr != MAP_FAILED) { + void *ident_ptr = fetch(mapped_file, 0, EI_NIDENT); + unsigned char ident[EI_NIDENT]; + if (!ident_ptr) { + ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); + if (path_allocated) { + free(path); + } + exit(1); + } + ft_memcpy(ident, ident_ptr, EI_NIDENT); + if (check_ident(ident) == FT_NM_FAILURE) { + ft_printf("sss", "ft_nm: ", path, ": file format not recognized\n"); + if (path_allocated) { + free(path); + } + exit (1); + } + if (ident[EI_CLASS] == ELFCLASS32) { + nm32(mapped_file); + } + else if (ident[EI_CLASS] == ELFCLASS64) { + nm64(mapped_file); + } + } return 0; } diff --git a/src/nm.c b/src/nm.c new file mode 100644 index 0000000..bbd48d4 --- /dev/null +++ b/src/nm.c @@ -0,0 +1,9 @@ +#include "ft_nm.h" + +void nm32(t_mapped_file mapped_file) { + (void)mapped_file; +} + +void nm64(t_mapped_file mapped_file) { + (void)mapped_file; +}