scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 37ff3b0c5179d524dc5704ab30bb92222e2c223f
parent fe458564c658e7f2630f62986da85c74188cc72a
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Mon,  5 Mar 2018 15:21:28 +0100

[nm] Split main.c in common and object part

This is the first step to be able to have ar working with
different file formats.

Diffstat:
Mnm/Makefile | 8+++++---
Mnm/main.c | 199++++++++++++++++---------------------------------------------------------------
Anm/myro.c | 141+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anm/nm.h | 15+++++++++++++++
Mrules.mk | 2++
5 files changed, 202 insertions(+), 163 deletions(-)

diff --git a/nm/Makefile b/nm/Makefile @@ -5,15 +5,17 @@ LIBDIR = $(PROJECTDIR)/lib/scc include $(PROJECTDIR)/rules.mk include $(LIBDIR)/libdep.mk -OBJ = main.o +OBJ = main.o myro.o all: nm +main.o: $(INCDIR)/scc.h $(INCDIR)/ar.h $(INCDIR)/arg.h +main.o: nm.h +myro.o: $(INCDIR)/scc.h $(INCDIR)/myro.h nm.h + nm: $(OBJ) $(LIBDIR)/libscc.a $(CC) $(SCC_LDFLAGS) $(OBJ) -lscc -o $@ -main.o: $(PROJECTDIR)/inc/scc.h $(PROJECTDIR)/inc/ar.h $(PROJECTDIR)/inc/myro.h - $(LIBDIR)/libscc.a: $(LIB-OBJ) +cd $(LIBDIR) && $(MAKE) diff --git a/nm/main.c b/nm/main.c @@ -10,33 +10,17 @@ static char sccsid[] = "@(#) ./nm/main.c"; #include "../inc/arg.h" #include "../inc/scc.h" -#include "../inc/myro.h" #include "../inc/ar.h" +#include "nm.h" char *argv0; -char *strings; -static int radix = 16; -static int Pflag; -static int Aflag; -static int vflag; -static int gflag; -static int uflag; -static int arflag; - -static int -object(char *fname, FILE *fp) -{ - char magic[MYROMAGIC_SIZ]; - fpos_t pos; - - fgetpos(fp, &pos); - fread(magic, sizeof(magic), 1, fp); - fsetpos(fp, &pos); - - if (!ferror(fp) && !strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ)) - return 1; - return 0; -} +int radix = 16; +int Pflag; +int Aflag; +int vflag; +int gflag; +int uflag; +int arflag; static int archive(char *fname, FILE *fp) @@ -53,51 +37,43 @@ archive(char *fname, FILE *fp) return 0; } -static int -cmp(const void *p1, const void *p2) +static void +ar(char *fname, FILE *fp) { - const struct myrosym *s1 = p1, *s2 = p2; + struct ar_hdr hdr; + long pos, siz; - if (vflag) - return s1->offset - s2->offset; - else - return strcmp(strings + s1->name, strings + s2->name); -} + arflag = 1; + fseek(fp, sizeof(struct ar_hdr), SEEK_CUR); -static int -typeof(struct myrosym *sym) -{ - int t, flags = sym->flags; + while (fread(&hdr, sizeof(hdr), 1, fp) == 1) { + pos = ftell(fp); + sscanf(hdr.ar_size, "%10ld", &siz); + if (pos == -1 || pos > LONG_MAX - siz) { + fprintf(stderr, + "nm: %s: overflow in size of archive\n", + fname); + return; + } + pos += siz; + if (siz & 1) + ++pos; - switch (sym->section) { - case MYRO_TEXT: - t = 't'; - break; - case MYRO_DATA: - t = 'd'; - break; - case MYRO_BSS: - t = (flags & MYROSYM_COMMON) ? 'c' : 'b'; - break; - case MYRO_ABS: - t = 'a'; - break; - default: - t = (flags & MYROSYM_UNDEF) ? 'u' : '?'; - break; + if (object(fname, fp)) { + nm(fname, hdr.ar_name, fp); + } else { + fprintf(stderr, + "nm: skipping member %s in archive %s\n", + hdr.ar_name, fname); + } + fseek(fp, pos, SEEK_SET); } - if (flags & MYROSYM_ABS) - t = 'a'; - if (flags & MYROSYM_EXTERN) - t = tolower(t); - return t; } -static void -print(char *file, char *member, struct myrosym *sym) +void +print(char *file, char *member, char *name, int type, unsigned long long off, long siz) { - char *fmt, *name = strings + sym->name; - int type = typeof(sym); + char *fmt; if (uflag && type != 'U') return; @@ -115,7 +91,7 @@ print(char *file, char *member, struct myrosym *sym) fmt = "%llu %llu"; else fmt = "%llx %llx"; - printf(fmt, sym->offset, sym->len); + printf(fmt, off, siz); } } else { if (type == 'U') @@ -126,109 +102,12 @@ print(char *file, char *member, struct myrosym *sym) fmt = "%016.16lld"; else fmt = "%016.16llx"; - printf(fmt, sym->offset); + printf(fmt, off); printf(" %c %s", type, name); } putchar('\n'); } -static void -nm(char *fname, char *member, FILE *fp) -{ - struct myrohdr hdr; - struct myrosym *syms = NULL; - size_t n, i; - long off; - - strings = NULL; - if (rdmyrohdr(fp, &hdr) < 0) { - fprintf(stderr, "nm: %s: incorrect header\n", member); - return; - } - - n = hdr.symsize / MYROSYM_SIZ; - if (n == 0) { - fprintf(stderr, "nm: %s: no name list\n", member); - return; - } - if (n > SIZE_MAX / sizeof(struct myrosym) || - hdr.symsize / MYROSYM_SIZ > SIZE_MAX || - hdr.strsize > SIZE_MAX) { - goto offset_overflow; - } - - syms = xmalloc(n * sizeof(struct myrosym)); - strings = xmalloc(hdr.strsize); - fread(strings, hdr.strsize, 1, fp); - if (feof(fp)) - goto free_arrays; - if ((off = ftell(fp)) < 0) - return; - if (off > LONG_MAX - hdr.secsize) - goto offset_overflow; - off += hdr.secsize; - - if (fseek(fp, off, SEEK_SET) < 0) - goto free_arrays; - - for (i = 0; i < n; ++i) { - if (rdmyrosym(fp, &syms[i]) < 0) - goto symbol_error; - if (syms[i].name >= hdr.strsize) - goto offset_overflow; - } - qsort(syms, n, sizeof(*syms), cmp); - for (i = 0; i < n; ++i) - print(fname, member, &syms[i]); - - -free_arrays: - free(syms); - free(strings); - return; - -symbol_error: - fprintf(stderr, "nm: %s: error reading symbols\n", fname); - goto free_arrays; - -offset_overflow: - fprintf(stderr, "nm: %s: overflow in headers of archive\n", - fname); - goto free_arrays; -} - -static void -ar(char *fname, FILE *fp) -{ - struct ar_hdr hdr; - long pos, siz; - - arflag = 1; - fseek(fp, sizeof(struct ar_hdr), SEEK_CUR); - - while (fread(&hdr, sizeof(hdr), 1, fp) == 1) { - pos = ftell(fp); - sscanf(hdr.ar_size, "%10ld", &siz); - if (pos == -1 || pos > LONG_MAX - siz) { - fprintf(stderr, - "nm: %s: overflow in size of archive\n", - fname); - return; - } - pos += siz; - if (siz & 1) - ++pos; - - if (object(fname, fp)) { - nm(fname, hdr.ar_name, fp); - } else { - fprintf(stderr, - "nm: skipping member %s in archive %s\n", - hdr.ar_name, fname); - } - fseek(fp, pos, SEEK_SET); - } -} void doit(char *fname) diff --git a/nm/myro.c b/nm/myro.c @@ -0,0 +1,141 @@ +static char sccsid[] = "@(#) ./nm/myro.c"; + +#include <ctype.h> +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../inc/scc.h" +#include "../inc/myro.h" +#include "nm.h" + +static char *strings; + +static int +typeof(struct myrosym *sym) +{ + int t, flags = sym->flags; + + switch (sym->section) { + case MYRO_TEXT: + t = 't'; + break; + case MYRO_DATA: + t = 'd'; + break; + case MYRO_BSS: + t = (flags & MYROSYM_COMMON) ? 'c' : 'b'; + break; + case MYRO_ABS: + t = 'a'; + break; + default: + t = (flags & MYROSYM_UNDEF) ? 'u' : '?'; + break; + } + if (flags & MYROSYM_ABS) + t = 'a'; + if (flags & MYROSYM_EXTERN) + t = tolower(t); + return t; +} + +static int +cmp(const void *p1, const void *p2) +{ + const struct myrosym *s1 = p1, *s2 = p2; + + if (vflag) + return s1->offset - s2->offset; + else + return strcmp(strings + s1->name, strings + s2->name); +} + +void +nm(char *fname, char *member, FILE *fp) +{ + struct myrohdr hdr; + struct myrosym *syms = NULL, *sym; + size_t n, i; + long off; + + strings = NULL; + if (rdmyrohdr(fp, &hdr) < 0) { + fprintf(stderr, "nm: %s: incorrect header\n", member); + return; + } + + n = hdr.symsize / MYROSYM_SIZ; + if (n == 0) { + fprintf(stderr, "nm: %s: no name list\n", member); + return; + } + if (n > SIZE_MAX / sizeof(struct myrosym) || + hdr.symsize / MYROSYM_SIZ > SIZE_MAX || + hdr.strsize > SIZE_MAX) { + goto offset_overflow; + } + + syms = xmalloc(n * sizeof(struct myrosym)); + strings = xmalloc(hdr.strsize); + fread(strings, hdr.strsize, 1, fp); + if (feof(fp)) + goto free_arrays; + if ((off = ftell(fp)) < 0) + return; + if (off > LONG_MAX - hdr.secsize) + goto offset_overflow; + off += hdr.secsize; + + if (fseek(fp, off, SEEK_SET) < 0) + goto free_arrays; + + for (i = 0; i < n; ++i) { + if (rdmyrosym(fp, &syms[i]) < 0) + goto symbol_error; + if (syms[i].name >= hdr.strsize) + goto offset_overflow; + } + qsort(syms, n, sizeof(*syms), cmp); + for (i = 0; i < n; ++i) { + sym = &sym[i]; + print(fname, + member, + strings + sym->name, + typeof(sym), + sym->offset, + sym->len); + } + +free_arrays: + free(syms); + free(strings); + return; + +symbol_error: + fprintf(stderr, "nm: %s: error reading symbols\n", fname); + goto free_arrays; + +offset_overflow: + fprintf(stderr, "nm: %s: overflow in headers of archive\n", + fname); + goto free_arrays; +} + +int +object(char *fname, FILE *fp) +{ + char magic[MYROMAGIC_SIZ]; + fpos_t pos; + + fgetpos(fp, &pos); + fread(magic, sizeof(magic), 1, fp); + fsetpos(fp, &pos); + + if (!ferror(fp) && !strncmp(magic, MYROMAGIC, MYROMAGIC_SIZ)) + return 1; + return 0; +} + diff --git a/nm/nm.h b/nm/nm.h @@ -0,0 +1,15 @@ + +/* main.c */ +extern void print(char *file, char *member, char *name, int type, unsigned long long off, long siz); + +/* object format file */ +extern void nm(char *fname, char *member, FILE *fp); +extern int object(char *fname, FILE *fp); + +extern int radix; +extern int Pflag; +extern int Aflag; +extern int vflag; +extern int gflag; +extern int uflag; +extern int arflag; diff --git a/rules.mk b/rules.mk @@ -1,5 +1,7 @@ include $(PROJECTDIR)/config.mk +INCDIR = $(PROJECTDIR)/inc/ + SCC_CFLAGS = $(MOREFLAGS) \ $(SYSCFLAGS) \ -g \