/* lkrel.c - .rel object file handling
Copyright (C) 1989-1995 Alan R. Baldwin
721 Berkeley St., Kent, Ohio 44240
Copyright (C) 2008-2010 Borut Razem, borut dot razem at siol dot net
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3, or (at your option) any
later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see . */
/*
* With contributions for the
* object libraries from
* Ken Hornstein
* kenh@cmf.nrl.navy.mil
*
*/
/*
* Extensions: P. Felber
*/
#include
#include "lk_readnl.h"
#include "aslink.h"
#include "lkrel.h"
int
is_rel (FILE * libfp)
{
int c;
long pos = ftell (libfp);
int ret = 0;
/* [XDQ][HL][234] */
if (((c = getc (libfp)) == 'X' || c == 'D' || c == 'Q') && ((c = getc (libfp)) == 'H' || c == 'L'))
{
switch (getc (libfp))
{
case '2':
case '3':
case '4':
switch (getc (libfp))
{
case '\r':
if (getc (libfp) == '\n')
ret = 1;
break;
case '\n':
ret = 1;
}
break;
case '\r':
if (getc (libfp) == '\n')
ret = 1;
break;
case '\n':
ret = 1;
}
}
else if (c == ';')
{
char buf[6];
if (fread (buf, 1, sizeof (buf), libfp) == sizeof (buf) && memcmp (buf, "!FILE ", 6) == 0)
ret = 1;
}
fseek (libfp, pos, SEEK_SET);
return ret;
}
/* Load a standalone or embedded .rel */
int
load_rel (FILE * libfp, long size)
{
if (is_rel (libfp))
{
char str[NINPUT];
long end;
end = (size >= 0) ? ftell (libfp) + size : -1;
while ((end < 0 || ftell (libfp) < end) && lk_readnl (str, sizeof (str), libfp) != NULL)
{
if (0 == strcmp (str, ""))
return 1;
ip = str;
link_main ();
}
return 1;
}
else
return 0;
}
int
enum_symbols (FILE * fp, long size, int (*func) (const char *symvoid, void *param), void *param)
{
char buf[NINPUT];
long end = (size >= 0) ? ftell (fp) + size : -1;
assert (func != NULL);
/*
* Read in the object file. Look for lines that
* begin with "S" and end with "D". These are
* symbol table definitions. If we find one, see
* if it is our symbol. Make sure we only read in
* our object file and don't go into the next one.
*/
while ((end < 0 || ftell (fp) < end) && lk_readnl (buf, sizeof (buf), fp) != NULL)
{
char symname[NINPUT];
char c;
/*
* When a 'T line' is found terminate file scan.
* All 'S line's preceed 'T line's in .REL files.
*/
if (buf[0] == 'T')
break;
/*
* Skip everything that's not a symbol record.
*/
if (buf[0] != 'S')
continue;
sscanf (buf, "S %s %c", symname, &c);
/* If it's an actual symbol, record it */
if (c == 'D')
{
if ((*func) (symname, param))
return 1;
}
}
return 0;
}