ack/util/amisc/ashow.c

257 lines
5.8 KiB
C
Raw Permalink Normal View History

1994-06-24 11:31:16 +00:00
static char rcsid[] = "$Id$";
1987-03-11 17:12:23 +00:00
/*
* show - make the contents of an ACK object file human readable.
*/
#include <stdlib.h>
1987-03-11 17:12:23 +00:00
#include <stdio.h>
2019-03-24 15:53:13 +00:00
#include <stdarg.h>
#include "object.h"
#include "out.h"
1987-03-11 17:12:23 +00:00
#define OK 0 /* Return value of gethead if Orl Korekt. */
#define BMASK 0xFF /* To extract least significant 8 bits from an int. */
2019-03-24 15:53:13 +00:00
/* Forward declarations */
static void show(register struct outhead *);
static void showflags(unsigned int);
static void showsect(void);
static void showrelo(void);
static void showname(struct outname *);
static char *myalloc(unsigned int);
static void error(char *, ...);
1987-03-11 17:12:23 +00:00
/* ARGSUSED */
2019-03-24 15:53:13 +00:00
int main(int argc, char **argv)
1987-03-11 17:12:23 +00:00
# define prog argv[0]
{
register char **arg = argv;
struct outhead header;
while (*++arg) {
if (! rd_open(*arg)) {
error("%s: cannot read %s\n", prog, *arg);
continue;
}
rd_ohead(&header);
if (BADMAGIC(header)) {
error("%s: %s not an ACK object file\n", prog, *arg);
} else {
printf("%s:\n", *arg);
show(&header);
}
rd_close();
}
2019-03-24 15:53:13 +00:00
return EXIT_SUCCESS;
1987-03-11 17:12:23 +00:00
}
/*
* Read an ACK object file from `fp' and show it in a human readable way.
* NB. The header has already been read and is in the struct outhead `headp'
* points to.
*/
2019-03-24 15:53:13 +00:00
static void show(register struct outhead *headp)
1987-03-11 17:12:23 +00:00
{
register int i;
register struct outname *np;
register struct outname *name; /* Dynamically allocated name-array. */
register char *string;/* Base of string area. */
printf("Version %d\n", headp->oh_stamp);
1991-12-18 09:45:26 +00:00
showflags((unsigned) headp->oh_flags);
1987-03-11 17:12:23 +00:00
/*
* Show all sections.
*/
for (i = 0; i < headp->oh_nsect; i++) {
printf("Section %d:\n", i);
showsect();
}
/*
* Show relocation information.
*/
for (i = 0; i < headp->oh_nrelo; i++) {
printf("Relocation record %d:\n", i);
showrelo();
}
/*
* We get all struct outname's and the strings in core first.
*/
name = (struct outname *) myalloc(headp->oh_nname * sizeof(struct outname));
1987-03-11 17:12:23 +00:00
string = myalloc((unsigned) headp->oh_nchar);
1987-04-08 15:10:26 +00:00
rd_name(name, headp->oh_nname);
1987-03-11 17:12:23 +00:00
for (np = &name[0]; np < &name[headp->oh_nname]; np++) {
1987-04-08 15:10:26 +00:00
if (np->on_foff != 0) {
np->on_foff -= OFF_CHAR(*headp);
if (np->on_foff >= headp->oh_nchar || np->on_foff < 0) {
np->on_mptr = "????";
}
else np->on_mptr = string + np->on_foff;
}
1987-03-11 17:12:23 +00:00
}
/*
* Transfer strings from file to core.
*/
rd_string(string, headp->oh_nchar);
/*
* Now we can show all names.
*/
2019-03-24 15:53:13 +00:00
for (np = &name[0]; np < &name[headp->oh_nname]; np++)
{
/* In C99 this should be "%td" but we are in ANSI C89,
* so we typecast explicitly to int here.
*/
printf("Name %d:\n", (int)(np - name));
1987-03-11 17:12:23 +00:00
showname(np);
}
}
/*
* Show flags from header.
*/
2019-03-24 15:53:13 +00:00
static void showflags(unsigned int flagword)
1987-03-11 17:12:23 +00:00
{
if (flagword & HF_LINK) printf("unresolved references left\n");
}
/*
* Show a section.
*/
2019-03-24 15:53:13 +00:00
static void showsect(void)
1987-03-11 17:12:23 +00:00
{
struct outsect section;
rd_sect(&section, 1);
printf("\tstartaddress in machine\t0x%lX\n", section.os_base);
printf("\tsection size in machine\t0x%lX\n", section.os_size);
printf("\tstartaddress in file\t0x%lX\n", section.os_foff);
printf("\tsection size in file\t0x%lX\n", section.os_flen);
1987-03-11 17:12:23 +00:00
printf("\tsection alignment\t%ld\n", section.os_lign);
}
/*
* Show a relocation record.
*/
2019-03-24 15:53:13 +00:00
static void showrelo(void)
1987-03-11 17:12:23 +00:00
{
struct outrelo relrec;
rd_relo(&relrec, 1);
switch (relrec.or_type & RELSZ) {
case RELO1:
printf("\t1 byte\n");
break;
case RELO2:
printf("\t2 bytes\n");
break;
case RELO2HI:
printf("\ttop 2 bytes of result\n");
break;
case RELO2HISAD:
printf("\ttop 2 bytes of result, sign adjusted\n");
break;
1987-03-11 17:12:23 +00:00
case RELO4:
printf("\t4 bytes\n");
break;
case RELOPPC:
printf("\tPowerPC 26-bit address\n");
break;
case RELOPPC_LIS:
printf("\tPowerPC lis instruction\n");
break;
case RELOVC4:
printf("\tVideoCore IV address in 32-bit instruction\n");
break;
case RELOMIPS:
printf("\tMIPS b or j instruction\n");
break;
1987-03-11 17:12:23 +00:00
default:
printf("\tunknown relocation type %d\n", relrec.or_type & RELSZ);
1987-03-11 17:12:23 +00:00
break;
}
if (relrec.or_type & RELPC) printf("\tpc relative\n");
if (relrec.or_type & RELBR) printf("\tbytes reversed\n");
if (relrec.or_type & RELWR) printf("\twords reversed\n");
printf("\treferencing section\t%d\n", (relrec.or_sect & BMASK) - S_MIN);
printf("\treferenced symbol index\t%d\n", relrec.or_nami);
printf("\treferencing address\t%ld\n", relrec.or_addr);
}
/*
* Show the name in the struct `namep' points to.
*/
2019-03-24 15:53:13 +00:00
static void showname(struct outname *namep)
1987-03-11 17:12:23 +00:00
{
if (namep->on_mptr)
printf("\t%s\n", namep->on_mptr);
else
printf("\tno name\n");
switch (namep->on_type & S_TYP) {
case S_UND:
printf("\tundefined\n");
break;
case S_ABS:
printf("\tabsolute\n");
break;
case S_CRS:
printf("\tcross reference\n");
1987-03-11 17:12:23 +00:00
default:
1987-04-08 15:10:26 +00:00
printf("\tin section %d\n", (namep->on_type & S_TYP) - S_MIN);
1987-03-11 17:12:23 +00:00
break;
}
if (namep->on_type & S_EXT) printf("\texternal\n");
if (namep->on_type & S_STB) {
printf("\tstab 0x%x\n", namep->on_type >> 8);
printf("\tdesc 0x%x\n", namep->on_desc);
}
else switch (namep->on_type & S_ETC) {
1987-03-11 17:12:23 +00:00
case S_SCT:
printf("\tsection name\n"); break;
case S_LIN:
printf("\thll source line item\n"); break;
case S_FIL:
printf("\thll source file item\n"); break;
case S_MOD:
printf("\tass src file item\n"); break;
case S_COM:
printf("\tcommon\n"); break;
case 0:
break;
default:
printf("\tstab 0x%x\n", namep->on_type >> 8);
printf("\tdesc 0x%x\n", namep->on_desc);
1987-03-11 17:12:23 +00:00
}
printf("\tvalue 0x%lX\n", namep->on_valu);
1987-03-11 17:12:23 +00:00
}
/*
* Core allocation via malloc() but fatal if no core.
*/
2019-03-24 15:53:13 +00:00
static char *myalloc(unsigned int u)
1987-03-11 17:12:23 +00:00
{
register char *rcp;
rcp = malloc(u);
2019-03-24 15:53:13 +00:00
if (rcp == (char *) NULL) {
1987-03-11 17:12:23 +00:00
error("Out of core\n");
2019-03-24 15:53:13 +00:00
exit(EXIT_FAILURE);
1987-03-11 17:12:23 +00:00
}
return rcp;
}
2019-03-24 15:53:13 +00:00
static void error(char *fmt, ...)
1987-03-11 17:12:23 +00:00
{
fflush(stdout);
2019-03-24 15:53:13 +00:00
/* Diagnostic print, no auto NL */
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
1987-03-11 17:12:23 +00:00
}
2019-03-24 15:53:13 +00:00
void rd_fatal(void)
1987-03-11 17:12:23 +00:00
{
error("Error in reading the object file\n");
exit(1);
}