find out how to get sections

This commit is contained in:
Gregory 2019-07-13 19:35:42 +03:00
parent dd68ed6846
commit 0ef5073711
5 changed files with 132 additions and 84 deletions

6
.editorconfig Normal file
View file

@ -0,0 +1,6 @@
root = true
[*]
indent_style = tab
indent_size = 4
trim_trailing_whitespace = true

1
.gitignore vendored
View file

@ -4,6 +4,7 @@
.vscode/* .vscode/*
!.vscode/launch.json !.vscode/launch.json
!.vscode/tasks.json !.vscode/tasks.json
/build
/bld /bld
/debug_bld /debug_bld
/out /out

View file

@ -13,4 +13,14 @@
#ifndef FT_NM_H #ifndef FT_NM_H
# define FT_NM_H # define FT_NM_H
# include <mach-o/loader.h>
# include <mach-o/nlist.h>
typedef struct load_command t_load_command;
typedef struct mach_header_64 t_mach_header_64;
typedef struct symtab_command t_symtab_command;
typedef struct segment_command_64 t_segment_command_64;
typedef struct nlist_64 t_nlist_64;
typedef struct section_64 t_section_64;
#endif #endif

View file

@ -11,6 +11,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
#include "libft.h" #include "libft.h"
#include "ft_nm.h"
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdio.h> #include <stdio.h>
@ -70,53 +71,64 @@ void close_file(int fd, char *file)
free(file); free(file);
} }
void handle_64(char *file) t_symtab_command *find_symbol_table_command(t_load_command *lc, uint32_t count)
{ {
struct mach_header_64 *hdr; uint32_t i;
struct load_command *load_cmd; t_symtab_command *sym_tab;
struct symtab_command *symtab_cmd;
struct segment_command_64 *segment_cmd;
hdr = (struct mach_header_64 *)file; sym_tab = NULL;
ft_putstr("64 bit mach-o file\n"); i = 0;
ft_putstr("# of cmds: "); while(i < count)
ft_putnbr(hdr->ncmds);
ft_putstr("\n");
ft_putstr("total cmds memory: ");
ft_putnbr(hdr->sizeofcmds);
ft_putstr("\n");
uint32_t load_cmd_offset = sizeof(struct mach_header_64);
uint32_t i = 0;
while (i < hdr->ncmds)
{ {
load_cmd = (struct load_command *)(file + load_cmd_offset); if (lc->cmd == LC_SYMTAB)
if (load_cmd->cmd == LC_SEGMENT_64)
{ {
segment_cmd = (struct segment_command_64 *)load_cmd; sym_tab = (t_symtab_command *)lc;
ft_putnbr(i); break;
ft_putchar(' ');
ft_putnbr(segment_cmd->nsects);
ft_putchar(' ');
ft_putstr(segment_cmd->segname);
ft_putchar('\n');
load_cmd_offset += load_cmd->cmdsize;
i++;
continue;
} }
if (load_cmd->cmd == LC_SYMTAB) lc = (t_load_command *)((uintptr_t)lc + lc->cmdsize);
{ i++;
symtab_cmd = (struct symtab_command *)load_cmd; }
ft_putstr("found symbol table load command\n"); return sym_tab;
ft_putstr("# of symbols: "); }
ft_putnbr(symtab_cmd->nsyms);
ft_putstr("\n");
uint32_t j = 0; t_section_64 *find_section(t_load_command *lc, uint32_t cmd_num, uint32_t section)
struct nlist_64 *symbol_table = (struct nlist_64 *) {
(file + symtab_cmd->symoff); uint32_t i;
struct nlist_64 symbol; uint32_t acc;
char *str_table = file + symtab_cmd->stroff; 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) while(j < symtab_cmd->nsyms)
{ {
symbol = symbol_table[j]; symbol = symbol_table[j];
@ -124,7 +136,7 @@ void handle_64(char *file)
int external = symbol.n_type & N_EXT; int external = symbol.n_type & N_EXT;
int debug = (symbol.n_type & N_STAB) != 0; int debug = (symbol.n_type & N_STAB) != 0;
int offset = external ? 0 : 32; int offset = external ? 0 : 32;
char *name = str_table + symbol.n_un.n_strx; char *name = string_table + symbol.n_un.n_strx;
if (debug) if (debug)
{ {
@ -146,8 +158,15 @@ void handle_64(char *file)
if (type == N_SECT) if (type == N_SECT)
{ {
// lookup in which section symbol is located // 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); 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_putchar(' ');
ft_putnbr(symbol.n_sect); ft_putnbr(symbol.n_sect);
} }
@ -156,10 +175,21 @@ void handle_64(char *file)
ft_putstr("\n"); ft_putstr("\n");
j++; j++;
} }
} }
load_cmd_offset += load_cmd->cmdsize;
i++; 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 handle_32(char *file)

View file

@ -0,0 +1 @@
销睨