ref: a4f55bc2a984f51aa2afef82f7f6257dece7a09d
dir: /src/libmach/object.c/
static char sccsid[] = "@(#) ./libmach/object.c"; #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <scc/mach.h> #include "libmach.h" struct format { int (*probe)(unsigned char *buf, char **name); int (*open)(FILE *fp, int type, Obj *obj); int (*read)(Obj *obj, Symbol *sym); void (*close)(Obj *obj); }; static struct format fmts[] = { [COFF32] = {coff32probe, coff32open, coff32read, coff32close}, [NFORMATS] = {NULL}, }; int objtest(FILE *fp, char **name) { int n, i; int (*fn)(unsigned char *, char **); fpos_t pos; unsigned char buf[NBYTES]; fgetpos(fp, &pos); n = fread(buf, NBYTES, 1, fp); fsetpos(fp, &pos); if (n != 1 || ferror(fp)) return -1; for (i = 0; i < NFORMATS; i++) { fn = fmts[i].probe; if (!fn) continue; n = (*fn)(buf, name); if (n == -1) continue; return n; } return -1; } int objopen(FILE *fp, int type, Obj *obj) { struct format *op; obj->type = type; obj->symtbl = NULL; obj->data = NULL; obj->nsym = obj->cursym = 0; op = &fmts[FORMAT(type)]; if ((*op->open)(fp, type, obj) < 0) return -1; return 0; } static int addsym(Obj *obj, Symbol *sym) { Symbol *p, *new; char *s; size_t len, siz = obj->nsym * sizeof(*sym); if (siz > SIZE_MAX - sizeof(*sym)) return -1; siz += sizeof(*sym); if ((p = realloc(obj->symtbl, siz)) == NULL) return -1; obj->symtbl = p; new = &p[obj->nsym]; new->type = sym->type; len = strlen(sym->name) + 1; if ((new->name = malloc(len)) == NULL) return -1; memcpy(new->name, sym->name, len); new->size = sym->size; new->value = sym->value; obj->nsym++; return 0; } int objread(FILE *fp, Obj *obj, int (*filter)(Symbol *)) { int r; Symbol sym, *p; struct format *op; op = &fmts[FORMAT(obj->type)]; while ((r = (*op->read)(obj, &sym)) > 0) { if (filter && (*filter)(&sym)) continue; addsym(obj, &sym); } return r; } void objclose(Obj *obj) { struct format *op; op = &fmts[FORMAT(obj->type)]; (*op->close)(obj); }