refactor
This commit is contained in:
parent
0ef5073711
commit
5b0cd41383
7 changed files with 276 additions and 204 deletions
60
inc/ft_nm.h
60
inc/ft_nm.h
|
@ -6,15 +6,15 @@
|
||||||
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2019/05/06 22:37:16 by foton #+# #+# */
|
/* Created: 2019/05/06 22:37:16 by foton #+# #+# */
|
||||||
/* Updated: 2019/05/06 22:40:14 by gtertysh ### ########.fr */
|
/* Updated: 2019/07/20 15:38:47 by gtertysh ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#ifndef FT_NM_H
|
#ifndef FT_NM_H
|
||||||
# define FT_NM_H
|
#define FT_NM_H
|
||||||
|
|
||||||
# include <mach-o/loader.h>
|
#include <mach-o/loader.h>
|
||||||
# include <mach-o/nlist.h>
|
#include <mach-o/nlist.h>
|
||||||
|
|
||||||
typedef struct load_command t_load_command;
|
typedef struct load_command t_load_command;
|
||||||
typedef struct mach_header_64 t_mach_header_64;
|
typedef struct mach_header_64 t_mach_header_64;
|
||||||
|
@ -23,4 +23,56 @@ typedef struct segment_command_64 t_segment_command_64;
|
||||||
typedef struct nlist_64 t_nlist_64;
|
typedef struct nlist_64 t_nlist_64;
|
||||||
typedef struct section_64 t_section_64;
|
typedef struct section_64 t_section_64;
|
||||||
|
|
||||||
|
typedef struct s_nm_file
|
||||||
|
{
|
||||||
|
void *file;
|
||||||
|
uint32_t size;
|
||||||
|
int fd;
|
||||||
|
} t_nm_file;
|
||||||
|
|
||||||
|
typedef struct s_nm_mach_64
|
||||||
|
{
|
||||||
|
t_mach_header_64 *header;
|
||||||
|
t_load_command *commands;
|
||||||
|
t_symtab_command *symbol_table_command;
|
||||||
|
t_nlist_64 *symbol_table;
|
||||||
|
char *string_table;
|
||||||
|
} t_nm_mach_64;
|
||||||
|
|
||||||
|
void init_file
|
||||||
|
(
|
||||||
|
t_nm_file *file
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
void open_file
|
||||||
|
(
|
||||||
|
const char *filename,
|
||||||
|
t_nm_file *file
|
||||||
|
);
|
||||||
|
|
||||||
|
void close_file
|
||||||
|
(
|
||||||
|
t_nm_file *file
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
void macho64
|
||||||
|
(
|
||||||
|
t_nm_file *file
|
||||||
|
);
|
||||||
|
|
||||||
|
t_symtab_command *find_symbol_table_command
|
||||||
|
(
|
||||||
|
t_load_command *lc,
|
||||||
|
uint32_t count
|
||||||
|
);
|
||||||
|
|
||||||
|
void print_addr
|
||||||
|
(
|
||||||
|
void *addr
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,7 +28,11 @@ inc = include_directories('inc')
|
||||||
install_headers('inc/ft_nm.h')
|
install_headers('inc/ft_nm.h')
|
||||||
|
|
||||||
sources = [
|
sources = [
|
||||||
'src/main.c'
|
'src/main.c',
|
||||||
|
'src/nm_file.c',
|
||||||
|
'src/macho64.c',
|
||||||
|
'src/print_address.c',
|
||||||
|
'src/find_symbol_table_command.c',
|
||||||
]
|
]
|
||||||
|
|
||||||
libft = subproject('libft')
|
libft = subproject('libft')
|
||||||
|
|
26
src/find_symbol_table_command.c
Normal file
26
src/find_symbol_table_command.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include "ft_nm.h"
|
||||||
|
#include "stddef.h"
|
||||||
|
|
||||||
|
t_symtab_command *find_symbol_table_command
|
||||||
|
(
|
||||||
|
t_load_command *lc,
|
||||||
|
uint32_t count
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
t_symtab_command *sym_tab;
|
||||||
|
|
||||||
|
sym_tab = NULL;
|
||||||
|
i = 0;
|
||||||
|
while(i < count)
|
||||||
|
{
|
||||||
|
if (lc->cmd == LC_SYMTAB)
|
||||||
|
{
|
||||||
|
sym_tab = (t_symtab_command *)lc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lc = (t_load_command *)((uintptr_t)lc + lc->cmdsize);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return sym_tab;
|
||||||
|
}
|
105
src/macho64.c
Normal file
105
src/macho64.c
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
#include "ft_nm.h"
|
||||||
|
#include "libft.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
t_section_64 *find_section
|
||||||
|
(
|
||||||
|
t_nm_mach_64 *mach64,
|
||||||
|
uint32_t index
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t acc;
|
||||||
|
t_load_command *lc;
|
||||||
|
t_section_64 *sections;
|
||||||
|
t_segment_command_64 *segment;
|
||||||
|
|
||||||
|
lc = mach64->commands;
|
||||||
|
acc = 0;
|
||||||
|
i = 0;
|
||||||
|
while(i < mach64->header->ncmds)
|
||||||
|
{
|
||||||
|
if (lc->cmd == LC_SEGMENT_64)
|
||||||
|
{
|
||||||
|
segment = (t_segment_command_64 *)lc;
|
||||||
|
if (segment->nsects + acc >= index)
|
||||||
|
{
|
||||||
|
sections = (t_section_64 *)((uintptr_t)segment +
|
||||||
|
sizeof(t_segment_command_64));
|
||||||
|
return (sections + index - acc - 1);
|
||||||
|
}
|
||||||
|
acc += segment->nsects;
|
||||||
|
}
|
||||||
|
lc = (t_load_command *)((uintptr_t)lc + lc->cmdsize);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_symbol_table(t_nm_mach_64 *mach64)
|
||||||
|
{
|
||||||
|
uint32_t j;
|
||||||
|
t_nlist_64 symbol;
|
||||||
|
t_section_64 *section;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
while(j < mach64->symbol_table_command->nsyms)
|
||||||
|
{
|
||||||
|
symbol = mach64->symbol_table[j];
|
||||||
|
int type = symbol.n_type & N_TYPE;
|
||||||
|
int external = symbol.n_type & N_EXT;
|
||||||
|
int debug = (symbol.n_type & N_STAB) != 0;
|
||||||
|
int offset = external ? 0 : 32;
|
||||||
|
char *name = mach64->string_table + symbol.n_un.n_strx;
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// some shit herustic should be used
|
||||||
|
// to determine to print address or not
|
||||||
|
if (symbol.n_value)
|
||||||
|
print_addr((void *)symbol.n_value);
|
||||||
|
else
|
||||||
|
ft_putstr(" ");
|
||||||
|
ft_putchar(' ');
|
||||||
|
if (type == N_UNDF)
|
||||||
|
ft_putchar('U' + offset);
|
||||||
|
if (type == N_ABS)
|
||||||
|
ft_putchar('A' + offset);
|
||||||
|
if (type == N_SECT)
|
||||||
|
{
|
||||||
|
// lookup in which section symbol is located
|
||||||
|
section = find_section(mach64, symbol.n_sect);
|
||||||
|
if(ft_strcmp(SECT_TEXT, section->sectname) == 0)
|
||||||
|
ft_putchar('T' + offset);
|
||||||
|
else if(ft_strcmp(SECT_DATA, section->sectname) == 0)
|
||||||
|
ft_putchar('D' + offset);
|
||||||
|
else if(ft_strcmp(SECT_BSS, section->sectname) == 0)
|
||||||
|
ft_putchar('B' + offset);
|
||||||
|
else
|
||||||
|
ft_putchar('S' + offset);
|
||||||
|
}
|
||||||
|
ft_putchar(' ');
|
||||||
|
ft_putstr(name);
|
||||||
|
ft_putstr("\n");
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void macho64(t_nm_file *file)
|
||||||
|
{
|
||||||
|
t_nm_mach_64 mach64;
|
||||||
|
|
||||||
|
mach64.header = (t_mach_header_64 *)file->file;
|
||||||
|
mach64.commands = (t_load_command *)(file->file + sizeof(t_mach_header_64));
|
||||||
|
mach64.symbol_table_command = find_symbol_table_command(mach64.commands,
|
||||||
|
mach64.header->ncmds);
|
||||||
|
mach64.symbol_table = (t_nlist_64 *)
|
||||||
|
(mach64.symbol_table_command->symoff + file->file);
|
||||||
|
mach64.string_table = (char *)
|
||||||
|
(mach64.symbol_table_command->stroff + file->file);
|
||||||
|
print_symbol_table(&mach64);
|
||||||
|
}
|
212
src/main.c
212
src/main.c
|
@ -3,220 +3,34 @@
|
||||||
/* ::: :::::::: */
|
/* ::: :::::::: */
|
||||||
/* main.c :+: :+: :+: */
|
/* main.c :+: :+: :+: */
|
||||||
/* +:+ +:+ +:+ */
|
/* +:+ +:+ +:+ */
|
||||||
/* By: gtertysh <marvin@42.fr> +#+ +:+ +#+ */
|
/* By: gtertysh <gtertysh@student.unit.ua> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2019/07/13 14:52:27 by gtertysh #+# #+# */
|
/* Created: 2019/07/13 14:52:27 by gtertysh #+# #+# */
|
||||||
/* Updated: 2019/07/13 14:52:29 by gtertysh ### ########.fr */
|
/* Updated: 2019/07/20 15:21:14 by gtertysh ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
#include "libft.h"
|
#include "libft.h"
|
||||||
#include "ft_nm.h"
|
#include "ft_nm.h"
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <mach-o/loader.h>
|
|
||||||
#include <mach-o/nlist.h>
|
|
||||||
|
|
||||||
static void print_addr(void *addr)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t bit_4;
|
|
||||||
size_t count;
|
|
||||||
|
|
||||||
count = sizeof(addr) * 2;
|
|
||||||
i = 0;
|
|
||||||
while (i < count)
|
|
||||||
{
|
|
||||||
bit_4 = ((size_t)addr >> ((count - i - 1) * 4)) & 0xf;
|
|
||||||
if (bit_4 < 10)
|
|
||||||
ft_putnbr(bit_4);
|
|
||||||
else
|
|
||||||
ft_putchar('a' + bit_4 - 10);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void open_file(const char *filename, int *fd, char **file)
|
|
||||||
{
|
|
||||||
struct stat stat_buff;
|
|
||||||
|
|
||||||
*fd = open(filename, O_RDONLY);
|
|
||||||
if (*fd == -1)
|
|
||||||
{
|
|
||||||
ft_putstr("can't open file\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
stat(filename, &stat_buff);
|
|
||||||
if (!S_ISREG(stat_buff.st_mode))
|
|
||||||
{
|
|
||||||
ft_putstr("not a regular file\n");
|
|
||||||
close(*fd);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
*file = NULL;
|
|
||||||
*file = malloc(stat_buff.st_size);
|
|
||||||
if (!*file)
|
|
||||||
{
|
|
||||||
ft_putstr("can't allocate memory\n");
|
|
||||||
close(*fd);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
read(*fd, *file, stat_buff.st_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void close_file(int fd, char *file)
|
|
||||||
{
|
|
||||||
close(fd);
|
|
||||||
free(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
t_symtab_command *find_symbol_table_command(t_load_command *lc, uint32_t count)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
t_symtab_command *sym_tab;
|
|
||||||
|
|
||||||
sym_tab = NULL;
|
|
||||||
i = 0;
|
|
||||||
while(i < count)
|
|
||||||
{
|
|
||||||
if (lc->cmd == LC_SYMTAB)
|
|
||||||
{
|
|
||||||
sym_tab = (t_symtab_command *)lc;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lc = (t_load_command *)((uintptr_t)lc + lc->cmdsize);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return sym_tab;
|
|
||||||
}
|
|
||||||
|
|
||||||
t_section_64 *find_section(t_load_command *lc, uint32_t cmd_num, uint32_t section)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint32_t acc;
|
|
||||||
t_section_64 *sections;
|
|
||||||
t_segment_command_64 *segment;
|
|
||||||
|
|
||||||
acc = 0;
|
|
||||||
i = 0;
|
|
||||||
while(i < cmd_num)
|
|
||||||
{
|
|
||||||
if (lc->cmd == LC_SEGMENT_64)
|
|
||||||
{
|
|
||||||
segment = (t_segment_command_64 *)lc;
|
|
||||||
if (segment->nsects + acc >= section)
|
|
||||||
{
|
|
||||||
sections = (t_section_64 *)((uintptr_t)segment + sizeof(t_segment_command_64));
|
|
||||||
return (sections + section - acc - 1);
|
|
||||||
}
|
|
||||||
acc += segment->nsects;
|
|
||||||
}
|
|
||||||
lc = (t_load_command *)((uintptr_t)lc + lc->cmdsize);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_symbol_table(t_symtab_command *symtab_cmd, char *file, t_load_command *load_commands, uint32_t cmd_num)
|
|
||||||
{
|
|
||||||
uint32_t j;
|
|
||||||
t_nlist_64 *symbol_table;
|
|
||||||
t_nlist_64 symbol;
|
|
||||||
t_section_64 *section;
|
|
||||||
char *string_table;
|
|
||||||
|
|
||||||
string_table = file + symtab_cmd->stroff;
|
|
||||||
symbol_table = (t_nlist_64 *)(file + symtab_cmd->symoff);
|
|
||||||
j = 0;
|
|
||||||
while(j < symtab_cmd->nsyms)
|
|
||||||
{
|
|
||||||
symbol = symbol_table[j];
|
|
||||||
int type = symbol.n_type & N_TYPE;
|
|
||||||
int external = symbol.n_type & N_EXT;
|
|
||||||
int debug = (symbol.n_type & N_STAB) != 0;
|
|
||||||
int offset = external ? 0 : 32;
|
|
||||||
char *name = string_table + symbol.n_un.n_strx;
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
j++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// some shit herustic should be used
|
|
||||||
// to determine to print address or not
|
|
||||||
if (symbol.n_value)
|
|
||||||
print_addr((void *)symbol.n_value);
|
|
||||||
else
|
|
||||||
ft_putstr(" ");
|
|
||||||
ft_putchar(' ');
|
|
||||||
if (type == N_UNDF)
|
|
||||||
ft_putchar('U' + offset);
|
|
||||||
if (type == N_ABS)
|
|
||||||
ft_putchar('A' + offset);
|
|
||||||
if (type == N_SECT)
|
|
||||||
{
|
|
||||||
// lookup in which section symbol is located
|
|
||||||
section = find_section(load_commands, cmd_num, symbol.n_sect);
|
|
||||||
if(ft_strcmp(SECT_TEXT, section->sectname) == 0)
|
|
||||||
ft_putchar('T' + offset);
|
|
||||||
else if(ft_strcmp(SECT_DATA, section->sectname) == 0)
|
|
||||||
ft_putchar('D' + offset);
|
|
||||||
else if(ft_strcmp(SECT_BSS, section->sectname) == 0)
|
|
||||||
ft_putchar('B' + offset);
|
|
||||||
else
|
|
||||||
ft_putchar('S' + offset);
|
|
||||||
ft_putchar(' ');
|
|
||||||
ft_putnbr(symbol.n_sect);
|
|
||||||
}
|
|
||||||
ft_putchar(' ');
|
|
||||||
ft_putstr(name);
|
|
||||||
ft_putstr("\n");
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_64(char *file)
|
|
||||||
{
|
|
||||||
t_mach_header_64 *hdr;
|
|
||||||
t_load_command *load_commands;
|
|
||||||
t_symtab_command *symtab_cmd;
|
|
||||||
// t_section_64 *sections;
|
|
||||||
// t_segment_command_64 *segment_cmd;
|
|
||||||
|
|
||||||
hdr = (t_mach_header_64 *)file;
|
|
||||||
load_commands = (t_load_command *)(file + sizeof(t_mach_header_64));
|
|
||||||
// sections = (t_section_64 *)(file + hdr->sizeofcmds + sizeof(t_mach_header_64));
|
|
||||||
symtab_cmd = find_symbol_table_command(load_commands, hdr->ncmds);
|
|
||||||
print_symbol_table(symtab_cmd, file, load_commands, hdr->ncmds);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handle_32(char *file)
|
|
||||||
{
|
|
||||||
(void)file;
|
|
||||||
ft_putstr("TODO\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
void hanldle_file(const char *filename)
|
void hanldle_file(const char *filename)
|
||||||
{
|
{
|
||||||
char *file;
|
t_nm_file file;
|
||||||
int fd;
|
uint32_t magic;
|
||||||
|
|
||||||
open_file(filename, &fd, &file);
|
|
||||||
uint32_t magic;
|
|
||||||
|
|
||||||
magic = *(uint32_t *)file;
|
|
||||||
|
|
||||||
|
init_file(&file);
|
||||||
|
open_file(filename, &file);
|
||||||
|
magic = *(uint32_t *)file.file;
|
||||||
if (magic == MH_MAGIC_64)
|
if (magic == MH_MAGIC_64)
|
||||||
handle_64(file);
|
macho64(&file);
|
||||||
else if (magic == MH_MAGIC)
|
// else if (magic == MH_MAGIC)
|
||||||
handle_64(file);
|
// handle_32(file);
|
||||||
else if (magic == MH_CIGAM || magic == MH_CIGAM_64)
|
// else if (magic == MH_CIGAM || magic == MH_CIGAM_64)
|
||||||
ft_putstr("do not support big endian binaries.");
|
// ft_putstr("do not support big endian binaries.");
|
||||||
else
|
else
|
||||||
ft_putstr("invalid magic number.");
|
ft_putstr("invalid magic number.");
|
||||||
close_file(fd, file);
|
close_file(&file);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
|
49
src/nm_file.c
Normal file
49
src/nm_file.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
|
||||||
|
#include "ft_nm.h"
|
||||||
|
#include "libft.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void init_file(t_nm_file *file)
|
||||||
|
{
|
||||||
|
file->fd = -1;
|
||||||
|
file->file = NULL;
|
||||||
|
file->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void open_file(const char *filename, t_nm_file *file)
|
||||||
|
{
|
||||||
|
struct stat stat_buff;
|
||||||
|
|
||||||
|
file->fd = open(filename, O_RDONLY);
|
||||||
|
if (file->fd == -1)
|
||||||
|
{
|
||||||
|
ft_putstr("can't open file\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
stat(filename, &stat_buff);
|
||||||
|
if (!S_ISREG(stat_buff.st_mode))
|
||||||
|
{
|
||||||
|
ft_putstr("not a regular file\n");
|
||||||
|
close(file->fd);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
file->size = stat_buff.st_size;
|
||||||
|
file->file = mmap(0, file->size, PROT_READ, MAP_PRIVATE, file->fd, 0);
|
||||||
|
if (file->file == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("can't mmap file");
|
||||||
|
close(file->fd);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_file(t_nm_file *file)
|
||||||
|
{
|
||||||
|
close(file->fd);
|
||||||
|
munmap(file->file, file->size);
|
||||||
|
}
|
22
src/print_address.c
Normal file
22
src/print_address.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#include "ft_nm.h"
|
||||||
|
#include "libft.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
void print_addr(void *addr)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t bit_4;
|
||||||
|
size_t count;
|
||||||
|
|
||||||
|
count = sizeof(addr) * 2;
|
||||||
|
i = 0;
|
||||||
|
while (i < count)
|
||||||
|
{
|
||||||
|
bit_4 = ((size_t)addr >> ((count - i - 1) * 4)) & 0xf;
|
||||||
|
if (bit_4 < 10)
|
||||||
|
ft_putnbr(bit_4);
|
||||||
|
else
|
||||||
|
ft_putchar('a' + bit_4 - 10);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue