This commit is contained in:
Jack Halford 2017-03-25 22:54:04 +01:00
parent fcc8dc3536
commit 25362e802e
13 changed files with 342 additions and 223 deletions

View file

@ -35,14 +35,15 @@ FT_NM_OBJ = $(OBJ_DIR)ft_nm.o
FT_OTOOL_OBJ= $(OBJ_DIR)ft_otool.o
SRC_BASE = \
dump_symtab.c\
fetch_header.c\
ft_nm.c\
ft_otool.c\
get_symbols.c\
hexdump.c\
mach_o_parse.c\
sym_dump.c\
sym_format.c\
sym_get.c
symbol_init.c
SRCS = $(addprefix $(SRC_DIR), $(SRC_BASE))
OBJS = $(addprefix $(OBJ_DIR), $(SRC_BASE:.c=.o))

View file

@ -6,7 +6,7 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/20 14:36:10 by jhalford #+# #+# */
/* Updated: 2017/03/23 17:04:06 by jhalford ### ########.fr */
/* Updated: 2017/03/25 22:50:17 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
@ -33,32 +33,36 @@ typedef enum e_symtype t_symtype;
typedef struct s_symbol t_symbol;
typedef struct s_symbolmap t_symbolmap;
typedef struct s_machodata t_machodata;
typedef struct s_symbol t_symbol;
enum e_symtype
{
SYM_UNDEF,
SYM_UNDF,
SYM_ABS,
SYM_TEXT,
SYM_DATA,
SYM_BSS,
SYM_COMMON,
SYM_DEBUG,
SYM_STAB,
SYM_OTHER,
SYM_INDIRECT,
SYM_INDR,
};
struct s_machodata
{
void *file;
t_list *sects;
t_list *symbols;
struct symtab_command *symtab;
struct dysymtab_command *dysymtab;
};
struct s_symbol
{
t_symtype type;
long value;
char *name;
int pos;
struct nlist_64 nlist;
char *string;
};
struct s_symbolmap
@ -68,15 +72,25 @@ struct s_symbolmap
};
extern t_symbolmap g_symbolmap[];
extern t_machodata *g_data;
t_list *sym_get(char *file);
int fetch_header(t_machodata *data, void *file);
int mach_o_parse(t_machodata *data);
int fetch_header(t_machodata *data);
int symbol_init(t_symbol *symbol,
char *stringtable, struct nlist_64 *array, int i);
int symbol_set(t_symbol *symbol);
int sym_format(t_symbol *symbol);
int sym_format_undf(t_symbolmap map, t_symbol *symbol);
int sym_format_text(t_symbolmap map, t_symbol *symbol);
int sym_format_stab(t_symbolmap map, t_symbol *symbol);
void dump_symtab(struct symtab_command *symtab, void *file);
void dump_dysymtab(struct dysymtab_command *dysymtab, void *file);
void dump_symbol(t_machodata *data, t_symbol *symbol);
void dump_machheader_64(t_machodata *data);
void dump_segment_64(t_machodata *data, struct segment_command_64 *seg);
void dump_symtab(t_machodata *data, struct symtab_command *symtab);
void dump_dysymtab(t_machodata *data, struct dysymtab_command *dysymtab);
void *hexdump(void *addr, unsigned int offset, unsigned int size);

View file

@ -0,0 +1,53 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* dump_symtab.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/25 19:39:15 by jhalford #+# #+# */
/* Updated: 2017/03/25 22:44:38 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
void dump_symtab(t_machodata *data, struct symtab_command *symtab)
{
int i;
char *stringtable;
t_symbol symbol;
struct nlist_64 *array;
ft_printf("{blu}{inv}struct symtab_command{eoc}\n");
stringtable = data->file + symtab->stroff;
array = (struct nlist_64*)(data->file + symtab->symoff);
i = -1;
while (++i < (int)symtab->nsyms)
{
symbol_init(&symbol, stringtable, array, i);
dump_symbol(data, &symbol);
}
}
void dump_dysymtab(t_machodata *data, struct dysymtab_command *dysymtab)
{
(void)data;
ft_printf("{blu}{inv}struct dysymtab_command{eoc}\n");
ft_printf("ilocalsym %i\n", dysymtab->ilocalsym);
ft_printf("nlocalsym %i\n", dysymtab->nlocalsym);
ft_printf("iextdefsym %i\n", dysymtab->iextdefsym);
ft_printf("nextdefsym %i\n", dysymtab->nextdefsym);
ft_printf("iundefsym %i\n", dysymtab->iundefsym);
ft_printf("nundefsym %i\n", dysymtab->nundefsym);
ft_printf("---------------\n");
ft_printf("ntoc %i\n", dysymtab->ntoc);
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
ft_printf("nextrefsyms %i\n", dysymtab->nextrefsyms);
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
ft_printf("nindirectsims %i\n", dysymtab->nindirectsyms);
ft_printf("nextrel %i\n", dysymtab->nextrel);
ft_printf("nlocrel %i\n", dysymtab->nlocrel);
ft_putendl("");
}

View file

@ -6,61 +6,100 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/23 15:56:37 by jhalford #+# #+# */
/* Updated: 2017/03/23 16:25:49 by jhalford ### ########.fr */
/* Updated: 2017/03/25 22:51:09 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
static void fetch_machheader64(t_machodata *data, void *file)
static void fetch_symtab(t_machodata *data, struct symtab_command *symtab)
{
int i;
t_symbol symbol;
char *stringtable;
struct nlist_64 *array;
data->symtab = symtab;
stringtable = data->file + symtab->stroff;
array = (struct nlist_64*)(data->file + symtab->symoff);
i = -1;
while (++i < (int)symtab->nsyms)
{
symbol_init(&symbol, stringtable, array, i);
ft_lsteadd(&data->symbols, ft_lstnew(&symbol, sizeof(symbol)));
}
}
static void fetch_sects(t_machodata *data, struct segment_command_64 *seg)
{
uint32_t nsects;
uint32_t i;
struct section_64 *sect;
nsects = seg->nsects;
sect = (void*)(seg + 1);
for (i = 0; i < nsects; i++)
{
/* DG("sect at %p (%s)", sect, sect->sectname); */
/* DG("data->sects at %p", ft_lstlast(data->sects)); */
ft_lsteadd(&data->sects, ft_lstnew(&sect, sizeof(sect)));
/* DG("data->sects at %p -> %p", ft_lstlast(data->sects), *(struct section_64*)ft_lstlast(data->sects)->content); */
/* DG("------------------"); */
sect = sect + 1;
}
}
static void fetch_machheader64(t_machodata *data)
{
uint32_t ncmds;
uint32_t i;
struct load_command *lc;
struct mach_header_64 *header = file;
struct mach_header_64 *header;
header = data->file;
ncmds = header->ncmds;
lc = (void*)(header + 1);
/* ft_printf("{blu}{inv}mach_header_64 w/ [%d] load_commands{eoc}\n", ncmds); */
for (i = 0; i < ncmds; i++)
{
/* ft_printf("{yel}{inv}load_command #%d: %#x{eoc}\n", i, lc->cmd); */
if (lc->cmd == LC_SYMTAB)
data->symtab = (struct symtab_command*)lc;
else if (lc->cmd == LC_DYSYMTAB)
data->dysymtab = (struct dysymtab_command*)lc;
fetch_symtab(data, (struct symtab_command*)lc);
/* else if (lc->cmd == LC_DYSYMTAB) */
/* data->dysymtab = (struct dysymtab_command*)lc; */
else if (lc->cmd == LC_SEGMENT_64)
fetch_sects(data, (struct segment_command_64*)lc);
lc = (void*)lc + lc->cmdsize;
}
}
static void fetch_fatheader(t_machodata *data, void *file)
{
struct fat_header *header = file;
struct fat_arch *arch;
int i;
int nfat_arch;
/* static void fetch_fatheader(t_machodata *data) */
/* { */
/* int i; */
/* int nfat_arch; */
/* struct fat_arch *arch; */
/* struct fat_header *header; */
nfat_arch = header->nfat_arch;
arch = (void*)(header + 1);
ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch);
for (i = 0; i < nfat_arch; i++)
{
ft_printf("CPU type=[%i]", arch->cputype);
fetch_machheader64(data, file + arch->offset);
arch += 1;
}
}
/* header = data->file; */
/* nfat_arch = header->nfat_arch; */
/* arch = (void*)(header + 1); */
/* ft_printf("{yel}{inv}FAT header w/ [%i] architures{eoc}\n", nfat_arch); */
/* for (i = 0; i < nfat_arch; i++) */
/* { */
/* ft_printf("CPU type=[%i]", arch->cputype); */
/* fetch_machheader64(data->file + arch->offset, data); */
/* arch += 1; */
/* } */
/* } */
int fetch_header(t_machodata *data, void *file)
int fetch_header(t_machodata *data)
{
uint32_t magic = *(int *)file;
int is_fat = IS_FAT(magic);
uint32_t magic = *(int *)data->file;
/* int is_fat = IS_FAT(magic); */
int is_64 = IS_MAGIC_64(magic);
if (is_64)
fetch_machheader64(data, file);
else if (is_fat)
fetch_fatheader(data, file);
fetch_machheader64(data);
/* else if (is_fat) */
/* fetch_fatheader(data); */
else
ft_printf("{red}unsupported architecture:{eoc} magic = %#x\n", magic);
return (0);

View file

@ -6,18 +6,26 @@
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/19 03:09:12 by jhalford #+# #+# */
/* Updated: 2017/03/23 17:04:13 by jhalford ### ########.fr */
/* Updated: 2017/03/25 22:49:54 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
t_machodata *g_data = NULL;
void nm(void *file)
{
t_list *symbols;
t_machodata data;
symbols = sym_get(file);
ft_lstiter(symbols, sym_format);
data.sects = NULL;
data.symbols = NULL;
data.file = file;
fetch_header(&data);
dump_symtab(&data, data.symtab);
g_data = &data;
ft_lstiter(data.symbols, symbol_set);
ft_lstiter(data.symbols, sym_format);
}
int main(int ac, char **av)
@ -27,7 +35,7 @@ int main(int ac, char **av)
struct stat buf;
if (ac != 2)
{
ft_dprintf(2, "Please give me an arg\n");
ft_dprintf(2, "USAGE PLACEHOLDER\n");
return (1);
}
if ((fd = open(av[1], O_RDONLY)) < 0)

View file

@ -1,63 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* dump_symtab.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/20 13:20:22 by jhalford #+# #+# */
/* Updated: 2017/03/23 16:49:03 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
static t_flag symtype(uint32_t i, struct dysymtab_command *dysym)
{
if (dysym->ilocalsym <= i && i < dysym->ilocalsym + dysym->nlocalsym)
return (SYM_DEBUG);
if (dysym->iextdefsym <= i && i < dysym->iextdefsym + dysym->nextdefsym)
return (SYM_TEXT);
if (dysym->iundefsym <= i && i < dysym->iundefsym + dysym->nundefsym)
return (SYM_UNDEF);
return (0);
}
t_list *sym_get(char *file)
{
int i;
char *stringtable;
char *string;
struct nlist_64 *array;
struct dylib_reference *ref;
t_symbol sym;
t_machodata data;
t_list *symbols;
fetch_header(&data, file);
stringtable = file + data.symtab->stroff;
symbols = NULL;
dump_symtab(data.symtab, file);
dump_dysymtab(data.dysymtab, file);
/* return (NULL); */
i = -1;
array = (struct nlist_64*)(file + data.symtab->symoff);
while (++i < (int)data.symtab->nsyms)
{
sym.name = stringtable + array[i].n_un.n_strx;
sym.type = symtype(i, data.dysymtab);
sym.value = 0;
ft_lsteadd(&symbols, ft_lstnew(&sym, sizeof(sym)));
}
return (symbols);
i = -1;
ref = (struct dylib_reference *)(file + data.dysymtab->indirectsymoff);
while (++i < (int)data.dysymtab->nindirectsyms)
{
string = stringtable + array[ref->isym].n_un.n_strx;
ft_printf("%i: %s,%#x\n", ref->isym, string, ref->flags);
ref += 1;
}
(void)file;
}

View file

@ -0,0 +1,19 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* mach_o_parse.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/25 20:56:50 by jhalford #+# #+# */
/* Updated: 2017/03/25 22:09:56 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
int mach_o_parse(t_machodata *data)
{
(void)data;
return (0);
}

View file

@ -2,19 +2,19 @@
void dump_section_64(struct section_64 *sect)
{
ft_printf("{blu}{inv}struct section_64{eoc}: segname=[%s], sectname=[%s]\n",
sect->segname, sect->sectname);
ft_printf("{blu}{inv}struct section_64{eoc} sectname=[%s]\n",
sect->sectname);
}
void dump_segment_64(struct segment_command_64 *seg, void *file)
void dump_segment_64(t_machodata *data, struct segment_command_64 *seg)
{
uint32_t nsects;
uint32_t i;
struct section_64 *sect;
(void)file;
(void)data;
nsects = seg->nsects;
ft_printf("{blu}{inv}struct segment_command_64{eoc}: segname=[%s], nsects=[%i]\n", seg->segname, nsects);
ft_printf("{blu}{inv}struct segment_command_64{eoc} segname=[%s], nsects=[%i]\n", seg->segname, nsects);
sect = (void*)(seg + 1);
for (i = 0; i < nsects; i++)
{
@ -23,41 +23,50 @@ void dump_segment_64(struct segment_command_64 *seg, void *file)
}
}
void dump_symtab(struct symtab_command *symtab, void *file)
{
int i;
char *stringtable;
char *string;
struct nlist_64 *array;
ft_printf("{blu}{inv}struct symtab_command{eoc}\n");
stringtable = file + symtab->stroff;
array = (struct nlist_64*)(file + symtab->symoff);
i = -1;
while (++i < (int)symtab->nsyms)
void dump_symbol(t_machodata *data, t_symbol *symbol)
{
uint8_t n_type; /* type flag, see below */
uint8_t n_sect; /* section number or NO_SECT */
uint16_t n_desc; /* see <mach-o/stab.h> */
uint64_t n_value; /* value of this symbol (or stab offset) */
char *sect_name;
n_type = symbol->nlist.n_type;
n_sect = symbol->nlist.n_sect;
n_desc = symbol->nlist.n_desc;
n_value = symbol->nlist.n_value;
DG("check");
sect_name = n_sect ?
(*(struct section_64**)ft_lst_at(data->sects, n_sect - 1)->content)->sectname : NULL;
DG("check2");
ft_printf("%i: %s\n\
\t%03b|%b|%x|%b\
\t%i(%s) \t%#06x \t%x\n",
symbol->pos, symbol->string,
(n_type & N_STAB) >> 5, (n_type & N_PEXT) >> 4,
n_type & N_TYPE, n_type & N_EXT,
n_sect, sect_name, n_desc, n_value);
}
void dump_machheader_64(t_machodata *data)
{
uint32_t ncmds;
uint32_t i;
struct load_command *lc;
struct mach_header_64 *header;
header = data->file;
ncmds = header->ncmds;
lc = (void*)(header + 1);
for (i = 0; i < ncmds; i++)
{
string = stringtable + array[i].n_un.n_strx;
ft_printf("%s\n", string);
if (lc->cmd == LC_SYMTAB)
dump_symtab(data, (struct symtab_command*)lc);
else if (lc->cmd == LC_DYSYMTAB)
dump_dysymtab(data, (struct dysymtab_command*)lc);
else if (lc->cmd == LC_SEGMENT_64)
dump_segment_64(data, (struct segment_command_64*)lc);
lc = (void*)lc + lc->cmdsize;
}
}
void dump_dysymtab(struct dysymtab_command *dysymtab, void *file)
{
(void)file;
ft_printf("{blu}{inv}struct dysymtab_command{eoc}\n");
ft_printf("ilocalsym %i\n", dysymtab->ilocalsym);
ft_printf("nlocalsym %i\n", dysymtab->nlocalsym);
ft_printf("iextdefsym %i\n", dysymtab->iextdefsym);
ft_printf("nextdefsym %i\n", dysymtab->nextdefsym);
ft_printf("iundefsym %i\n", dysymtab->iundefsym);
ft_printf("nundefsym %i\n", dysymtab->nundefsym);
ft_printf("---------------\n");
ft_printf("ntoc %i\n", dysymtab->ntoc);
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
ft_printf("nextrefsyms %i\n", dysymtab->nextrefsyms);
ft_printf("nmodtab %i\n", dysymtab->nmodtab);
ft_printf("nindirectsims %i\n", dysymtab->nindirectsyms);
ft_printf("nextrel %i\n", dysymtab->nextrel);
ft_printf("nlocrel %i\n", dysymtab->nlocrel);
ft_putendl("");
}

View file

@ -2,20 +2,42 @@
t_symbolmap g_symbolmap[] =
{
{'U', NULL},
{'U', sym_format_undf},
{'A', NULL},
{'T', sym_format_text},
{'D', NULL},
{'B', NULL},
{'C', NULL},
{'-', NULL},
{'-', sym_format_stab},
{'S', NULL},
{'I', NULL},
};
int sym_format_undf(t_symbolmap map, t_symbol *symbol)
{
ft_printf("%16s %c %s\n", " ", map.c, symbol->string);
return (0);
}
int sym_format_text(t_symbolmap map, t_symbol *symbol)
{
ft_printf("%016x %c %s\n", symbol->value, map.c, symbol->name);
char c;
c = symbol->nlist.n_type & N_EXT ? 'T' : 't';
ft_printf("%016x %c %s\n", symbol->nlist.n_value, map.c, symbol->string);
return (0);
}
int sym_format_stab(t_symbolmap map, t_symbol *symbol)
{
struct nlist_64 stab;
stab = symbol->nlist;
ft_printf("%016x %c %02x %04b %#x %s\n",
stab.n_value, map.c,
stab.n_sect, stab.n_desc, stab.n_type,
symbol->string);
return (0);
}
@ -27,6 +49,7 @@ int sym_format(t_symbol *symbol)
if (map.format)
map.format(map, symbol);
else
ft_printf("%16s %c %s\n", " ", map.c, symbol->name);
ft_printf("%016x %c %s\n",
symbol->nlist.n_value, map.c, symbol->string);
return (0);
}

View file

@ -1,64 +0,0 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* dump_symtab.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/02/20 13:20:22 by jhalford #+# #+# */
/* Updated: 2017/03/23 16:49:03 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
static t_flag get_symtype(uint32_t i, struct dysymtab_command *dysym)
{
if (dysym->ilocalsym <= i && i <= dysym->ilocalsym + dysym->nlocalsym)
return (SYM_DEBUG);
if (dysym->iextdefsym <= i && i <= dysym->iextdefsym + dysym->nextdefsym)
return (SYM_TEXT);
if (dysym->iundefsym <= i && i <= dysym->iundefsym + dysym->nundefsym)
return (SYM_UNDEF);
return (0);
}
t_list *get_symbols(char *file)
{
int i;
int nsyms;
char *stringtable;
char *string;
struct nlist_64 *array;
struct dylib_reference *ref;
t_symbol sym;
t_machodata data;
t_list *symbols;
fetch_header(&data, file);
nsyms = data.symtab->nsyms;
array = (struct nlist_64*)(file + data.symtab->symoff);
stringtable = file + data.symtab->stroff;
ft_printf("LC_SYMTAB [%d] symbols:\n", data.symtab->nsyms);
i = -1;
symbols = NULL;
while (++i < nsyms)
{
sym.name = stringtable + array[i].n_un.n_strx;
sym.type = get_symtype(i, data.dysymtab);
sym.value = 0;
ft_lstadd(&symbols, ft_lstnew(&sym, sizeof(sym)));
}
return (symbols);
ft_putendl("");
ref = (struct dylib_reference *)(file + data.dysymtab->indirectsymoff);
i = -1;
while (++i < (int)data.dysymtab->nindirectsyms)
{
string = stringtable + array[ref->isym].n_un.n_strx;
ft_printf("%i: %s,%#x\n", ref->isym, string, ref->flags);
ref += 1;
}
(void)file;
}

View file

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* symbol_init.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: jhalford <jack@crans.org> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2017/03/25 21:22:06 by jhalford #+# #+# */
/* Updated: 2017/03/25 22:53:07 by jhalford ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_nm_otool.h"
t_machodata *g_data;
int symbol_init(t_symbol *symbol, char *stringtable, struct nlist_64 *array, int i)
{
symbol->type = 0;
symbol->pos = i;
symbol->nlist = array[i];
symbol->string = stringtable + array[i].n_un.n_strx;
return (0);
}
int symbol_set(t_symbol *symbol)
{
struct nlist_64 nlist;
uint8_t n_type;
uint8_t type_mask;
char *sect_name;
nlist = symbol->nlist;
n_type = symbol->nlist.n_type;
type_mask = n_type & N_TYPE;
sect_name = symbol->nlist.n_sect ?
(*(struct section_64**)ft_lst_at(g_data->sects,
symbol->nlist.n_sect - 1)->content)->sectname : NULL;
if (n_type & N_STAB)
symbol->type = SYM_STAB;
else if (type_mask == N_UNDF && n_type & N_EXT && nlist.n_value != 0)
symbol->type = SYM_COMMON;
else if (type_mask == N_UNDF)
symbol->type = SYM_UNDF;
else if (type_mask == N_SECT && ft_strcmp("__text", sect_name) == 0)
symbol->type = SYM_TEXT;
else if (type_mask == N_SECT && ft_strcmp("__data", sect_name) == 0)
symbol->type = SYM_DATA;
else if (type_mask == N_ABS)
symbol->type = SYM_ABS;
else if (type_mask == N_INDR)
symbol->type = SYM_INDR;
else
symbol->type = SYM_UNDF;
return (0);
}

View file

@ -0,0 +1 @@
gcc -g3 stabs_define.c -w -o stabs_define

View file

@ -0,0 +1,23 @@
#define NONE 42
#define TWO(a, b) (a + (a) + 2 * b)
#define ONE(c) (c + 19)
main(int argc, char *argv[])
{
func(NONE, TWO(10, 11));
func(NONE, ONE(23));
#undef ONE
#define ONE(c) (c + 23)
func(NONE, ONE(-23));
return (0);
}
int global;
func(int arg1, int arg2)
{
global = arg1 + arg2;
}