ref: d31f41ad68c39eb244316ae777bcddfb98beca17
parent: a032cacd156cbd3605b5c8f4c4c1149d56711eaa
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Wed Aug 28 06:51:23 EDT 2019
[libmach] Add getsec()
--- a/include/scc/scc/mach.h
+++ b/include/scc/scc/mach.h
@@ -1,9 +1,5 @@
-#define NR_SYMHASH 32
-
-typedef struct objsec Objsec;
typedef struct symbol Symbol;
-typedef struct objseg Objseg;
-typedef struct objops Objops;
+typedef struct section Section;
typedef struct obj Obj;
enum sectype {
@@ -17,15 +13,14 @@
SSHARED = 1 << 7,
};
-struct objsec {
+struct section {
char *name;
- int id;
+ unsigned long long base;
+ unsigned long long size;
+ unsigned flags;
int type;
+ int index;
int align;
- unsigned flags;
- long seek;
- unsigned long long size, base;
- Objsec *next;
};
struct symbol {
@@ -32,38 +27,11 @@
char *name;
unsigned long long size;
unsigned long long value;
- void *aux;
int index;
char class;
char type;
};
-struct objseg {
- unsigned long long size;
- unsigned long long value;
-};
-
-struct objops {
- int (*probe)(unsigned char *buf, char **name);
- int (*new)(Obj *obj);
- void (*del)(Obj *obj);
- int (*read)(Obj *obj, FILE *fp);
- int (*write)(Obj *obj, FILE *fp);
- int (*strip)(Obj *obj);
- int (*addr2line)(Obj *, unsigned long long , char *, int *);
- Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym);
- int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp);
- int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp);
-};
-
-struct obj {
- char *index;
- Objops *ops;
- int type;
- long pos;
- void *data;
-};
-
extern int archive(FILE *fp);
extern long armember(FILE *fp, char *member);
@@ -70,6 +38,11 @@
extern int objtype(FILE *fp, char **name);
extern Obj *newobj(int type);
extern void delobj(Obj *obj);
+
extern int readobj(Obj *obj, FILE *fp);
+extern int writeobj(Obj *obj, FILE *fp);
+
+extern int strip(Obj *obj);
+
extern Symbol *getsym(Obj *obj, long *index, Symbol *sym);
-extern int strip(Obj *obj);
\ No newline at end of file
+extern Section *getsec(Obj *obj, long *index, Section *sec);
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -6,8 +6,8 @@
TARGET = $(BINDIR)/nm \
$(BINDIR)/ar \
$(BINDIR)/strip \
+ $(BINDIR)/size \
-# $(BINDIR)/size \
# $(BINDIR)/ranlib \
# $(BINDIR)/objdump \
# $(BINDIR)/objcopy \
--- a/src/cmd/size.c
+++ b/src/cmd/size.c
@@ -38,27 +38,27 @@
}
static void
-newobject(FILE *fp, int type)
+sizeobj(FILE *fp, int type)
{
- int i;
+ long i;
Obj *obj;
unsigned long long total, *p;
- Objsec *sp;
struct sizes siz;
+ Section sec;
- if ((obj = objnew(type)) == NULL) {
- error("out of memory");
+ if ((obj = newobj(type)) == NULL) {
+ error(strerror(errno));
return;
}
- if ((*obj->ops->read)(obj, fp) < 0) {
- error("file corrupted");
+ if (readobj(obj, fp) < 0) {
+ error(strerror(errno));
goto err;
}
siz.text = siz.data = siz.bss = 0;
- for (sp = obj->secs; sp; sp = sp->next) {
- switch (sp->type) {
+ for (i = 0; getsec(obj, &i, &sec); i++) {
+ switch (sec.type) {
case 'R':
case 'T':
p = &siz.text;
@@ -73,12 +73,12 @@
continue;
}
- if (*p > ULLONG_MAX - sp->size) {
+ if (*p > ULLONG_MAX - sec.size) {
error("integer overflow");
goto err;
}
- *p += sp->size;
+ *p += sec.size;
}
total = siz.text + siz.data + siz.bss;
@@ -94,24 +94,36 @@
ttotal += total;
err:
- (*obj->ops->del)(obj);
+ delobj(obj);
}
static void
-newlib(FILE *fp)
+sizelib(FILE *fp)
{
int t;
- long r;
+ long off, cur;
char memb[SARNAM+1];
- while ((r = armember(fp, memb)) > 0) {
- membname = memb;
- if ((t = objtype(fp, NULL)) != -1)
- newobject(fp, t);
- membname = NULL;
+ for (;;) {
+ cur = ftell(fp);
+ off = armember(fp, memb);
+ switch (off) {
+ case -1:
+ error("library corrupted");
+ if (ferror(fp))
+ error(strerror(errno));
+ case 0:
+ return;
+ default:
+ membname = memb;
+ if ((t = objtype(fp, NULL)) != -1)
+ sizeobj(fp, t);
+ membname = NULL;
+ fseek(fp, cur, SEEK_SET);
+ fseek(fp, off, SEEK_CUR);
+ break;
+ }
}
- if (r < 0)
- error("library corrupted");
}
static void
@@ -127,15 +139,12 @@
}
if ((t = objtype(fp, NULL)) != -1)
- newobject(fp, t);
+ sizeobj(fp, t);
else if (archive(fp))
- newlib(fp);
+ sizelib(fp);
else
error("bad format");
- if (ferror(fp))
- error(strerror(errno));
-
fclose(fp);
}
@@ -175,8 +184,10 @@
}
if (fflush(stdout)) {
- filename = "stdout";
- error(strerror(errno));
+ fprintf(stderr,
+ "size: error writing in output:%s\n",
+ strerror(errno));
+ status = 1;
}
return status;
--- a/src/libmach/Makefile
+++ b/src/libmach/Makefile
@@ -14,6 +14,7 @@
readobj.o \
writeobj.o \
getsym.o \
+ getsec.o \
strip.o \
pack.o \
unpack.o \
--- a/src/libmach/coff32/Makefile
+++ b/src/libmach/coff32/Makefile
@@ -17,6 +17,7 @@
coff32getidx.o \
coff32addr2line.o \
coff32getsym.o \
+ coff32getsec.o \
all: $(OBJS)
--- a/src/libmach/coff32/coff32.c
+++ b/src/libmach/coff32/coff32.c
@@ -5,7 +5,7 @@
#include "../libmach.h"
#include "coff32.h"
-Objops coff32 = {
+struct objops coff32 = {
.probe = coff32probe,
.new = coff32new,
.read = coff32read,
@@ -16,4 +16,5 @@
.del = coff32del,
.write = coff32write,
.getsym = coff32getsym,
+ .getsec = coff32getsec,
};
--- a/src/libmach/coff32/coff32.h
+++ b/src/libmach/coff32/coff32.h
@@ -39,4 +39,5 @@
extern int coff32xgetidx(int order,
long *nsyms, char ***namep, long **offsp, FILE *fp);
-extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);
\ No newline at end of file
+extern Symbol *coff32getsym(Obj *obj, long *idx, Symbol *sym);
+extern Section *coff32getsec(Obj *obj, long *idx, Section *sec);
--- a/src/libmach/getsym.c
+++ b/src/libmach/getsym.c
@@ -2,6 +2,8 @@
#include <scc/mach.h>
+#include "libmach.h"
+
Symbol *
getsym(Obj *obj, long *index, Symbol *sym)
{
--- a/src/libmach/libmach.h
+++ b/src/libmach/libmach.h
@@ -4,6 +4,8 @@
#define ARCH(t) (((t) >> 5) & 0x1f)
#define ORDER(t) (((t) >> 10) & 0x1f)
+typedef struct objops Objops;
+
enum objformat {
COFF32,
NFORMATS,
@@ -21,6 +23,33 @@
enum order {
LITTLE_ENDIAN,
BIG_ENDIAN,
+};
+
+struct objops {
+ int (*probe)(unsigned char *buf, char **name);
+
+ int (*new)(Obj *obj);
+ void (*del)(Obj *obj);
+
+ int (*read)(Obj *obj, FILE *fp);
+ int (*write)(Obj *obj, FILE *fp);
+
+ int (*strip)(Obj *obj);
+ int (*addr2line)(Obj *, unsigned long long , char *, int *);
+
+ Symbol *(*getsym)(Obj *obj, long *index, Symbol *sym);
+ Section *(*getsec)(Obj *obj, long *index, Section *sec);
+
+ int (*setidx)(long nsyms, char *names[], long offset[], FILE *fp);
+ int (*getidx)(long *nsyms, char ***names, long **offset, FILE *fp);
+};
+
+struct obj {
+ char *index;
+ struct objops *ops;
+ int type;
+ long pos;
+ void *data;
};
/* common functions */
--- a/src/libmach/readobj.c
+++ b/src/libmach/readobj.c
@@ -2,6 +2,8 @@
#include <scc/mach.h>
+#include "libmach.h"
+
int
readobj(Obj *obj, FILE *fp)
{