ref: ff9c7adf8c9068f8be72f7b1cff723224bb03719
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"
int
objtype(FILE *fp, char **name)
{
int n, i;
int (*fn)(unsigned char *, char **);
struct format **bp, *op;
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 (bp = objfmt; bp < &objfmt[NFORMATS]; ++bp) {
op = *bp;
if (!op || !op->probe)
continue;
n = (*op->probe)(buf, name);
if (n == -1)
continue;
return n;
}
return -1;
}
Symbol *
objlookup(Obj *obj, char *name)
{
unsigned h;
size_t len;
char *s;
Symbol *sym;
h = 0;
for (s = name; *s; s++)
h += *s;
h %= NR_SYMHASH;
for (sym = obj->htab[h]; sym; sym = sym->hash) {
if (!strcmp(name, sym->name))
return sym;
}
if ((sym = malloc(sizeof(*sym))) == NULL)
return NULL;
len = strlen(name) + 1;
if ((s = malloc(len)) == NULL) {
free(sym);
return NULL;
}
sym->name = memcpy(s, name, len);
sym->type = 'U';
sym->size = 0;
sym->value = 0;
sym->hash = obj->htab[h];
obj->htab[h] = sym;
sym->next = obj->head;
obj->head = sym;
return sym;
}
int
objwrite(Obj *obj, FILE *fp)
{
int fmt;
struct format *op;
fmt = FORMAT(obj->type);
if (fmt >= NFORMATS)
return -1;
op = objfmt[fmt];
if ((*op->write)(obj, fp) < 0)
return -1;
return 0;
}
int
objread(Obj *obj, FILE *fp)
{
int fmt;
struct format *op;
fmt = FORMAT(obj->type);
if (fmt >= NFORMATS)
return -1;
op = objfmt[fmt];
if ((*op->read)(obj, fp) < 0)
return -1;
return 0;
}
Obj *
objnew(int type)
{
Obj *obj;
int fmt;
struct format *op;
fmt = FORMAT(type);
if (fmt >= NFORMATS)
return NULL;
if ((obj = malloc(sizeof(*obj))) == NULL)
return NULL;
obj->type = type;
obj->head = NULL;
memset(obj->htab, 0, sizeof(obj->htab));
op = objfmt[fmt];
if ((*op->new)(obj) < 0) {
free(obj);
return NULL;
}
return obj;
}
int
objtraverse(Obj *obj, int (*fn)(Symbol *, void *), void *data)
{
Symbol *sym;
for (sym = obj->head; sym; sym = sym->next) {
if (!(*fn)(sym, data))
return 0;
}
return 1;
}
static void
delsyms(Obj *obj)
{
Symbol *sym, *next;
for (sym = obj->head; sym; sym = next) {
next = sym->next;
free(sym->name);
free(sym);
}
obj->head = NULL;
memset(obj->htab, 0, sizeof(obj->htab));
}
int
objreset(Obj *obj)
{
int fmt;
struct format *op;
fmt = FORMAT(obj->type);
if (fmt < NFORMATS)
return -1;
op = objfmt[fmt];
(*op->del)(obj);
delsyms(obj);
return 0;
}
int
objdel(Obj *obj)
{
if (objreset(obj) < 0)
return -1;
free(obj);
}
int
objstrip(Obj *obj)
{
int fmt;
struct format *op;
fmt = FORMAT(obj->type);
if (fmt >= NFORMATS)
return -1;
op = objfmt[fmt];
(*op->strip)(obj);
delsyms(obj);
return 0;
}
int
objsize(Obj *obj,
unsigned long long *text,
unsigned long long *data,
unsigned long long *bss)
{
int fmt;
struct format *op;
fmt = FORMAT(obj->type);
if (fmt >= NFORMATS)
return -1;
op = objfmt[fmt];
return (*op->size)(obj, text, data, bss);
}
int
addr2line(Obj *obj, unsigned long long addr, char *fname, int *line)
{
/* TODO */
return -1;
}