/*
* Copyright (c) 1995-96 Mats O Jansson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined (HAVE_NBTOOL_CONFIG_H)
# include "nbtool_config.h"
#else
# include "port.h"
#endif /* defined (HAVE_NBTOOL_CONFIG_H) */
#ifndef lint
__RCSID("$NetBSD: file.c,v 1.20 2024/12/03 05:57:02 kalvisd Exp $");
#endif
#ifndef NOAOUT
# if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__) || defined(__OpenBSD__)
# include <sys/exec_aout.h>
# endif
# if defined(__bsdi__)
# define NOAOUT
# endif
# if defined(__FreeBSD__)
# include <sys/imgact_aout.h>
# endif
# if !defined(MID_VAX)
# define MID_VAX 150
# endif
# if !defined(MID_VAX1K)
# define MID_VAX1K 140
# endif
#endif /* NOAOUT */
#ifndef NOELF
# if defined (HAVE_NBTOOL_CONFIG_H) || defined(__NetBSD__)
# include <sys/exec_elf.h>
# else
# define NOELF
# endif
#endif /* NOELF */
#ifndef NOAOUT
static int getCLBYTES(int);
static int getMID(int, int);
#endif
const char *
FileTypeName(mopd_imagetype type)
{
switch (type) {
case IMAGE_TYPE_MOP:
return ("MOP");
case IMAGE_TYPE_ELF32:
return ("Elf32");
case IMAGE_TYPE_AOUT:
return ("a.out");
}
abort();
}
void
mopFilePutLX(u_char *buf, int idx, u_int32_t value, int cnt)
{
int i;
for (i = 0; i < cnt; i++) {
buf[idx+i] = value % 256;
value = value / 256;
}
}
void
mopFilePutBX(u_char *buf, int idx, u_int32_t value, int cnt)
{
int i;
for (i = 0; i < cnt; i++) {
buf[idx+cnt-1-i] = value % 256;
value = value / 256;
}
}
u_int32_t
mopFileGetLX(u_char *buf, int idx, int cnt)
{
u_int32_t ret = 0;
int i;
for (i = 0; i < cnt; i++) {
int j = idx + cnt - 1 - i;
if (j < 0)
abort();
ret = ret * 256 + buf[j];
}
return(ret);
}
u_int32_t
mopFileGetBX(u_char *buf, int idx, int cnt)
{
u_int32_t ret = 0;
int i;
for (i = 0; i < cnt; i++) {
int j = idx + i;
if (j < 0)
abort();
ret = ret * 256 + buf[j];
}
return(ret);
}
void
mopFileSwapX(u_char *buf, int idx, int cnt)
{
int i;
u_char c;
for (i = 0; i < (cnt / 2); i++) {
c = buf[idx+i];
buf[idx+i] = buf[idx+cnt-1-i];
buf[idx+cnt-1-i] = c;
}
}
int
CheckMopFile(int fd)
{
u_char header[512];
short image_type;
switch(image_type) {
case IHD_C_NATIVE: /* Native mode image (VAX) */
case IHD_C_RSX: /* RSX image produced by TKB */
case IHD_C_BPA: /* BASIC plus analog */
case IHD_C_ALIAS: /* Alias */
case IHD_C_CLI: /* Image is CLI */
case IHD_C_PMAX: /* PMAX system image */
case IHD_C_ALPHA: /* ALPHA system image */
break;
default:
return(-1);
}
return(0);
}
int
GetMopFileInfo(struct dllist *dl)
{
u_char header[512];
short image_type;
u_int32_t load_addr, xfr_addr, isd, iha, hbcnt, isize;
if (read(dl->ldfd, header, 512) != 512)
return(-1);
/*
* If we're in the file-backed part of the section,
* transmit some of the file.
*/
if (secoff < dlslot->e_sections[sec].s_fsize) {
bsz = dlslot->e_sections[sec].s_fsize - secoff;
if (bsz > dlslot->dl_bsz)
bsz = dlslot->dl_bsz;
if (lseek(dlslot->ldfd,
dlslot->e_sections[sec].s_foff + secoff,
SEEK_SET) == (off_t) -1)
return (-1);
len = read(dlslot->ldfd, buf, bsz);
}
/*
* Otherwise, if we're in the zero-fill part of the
* section, transmit some zeros.
*/
else if (secoff < (dlslot->e_sections[sec].s_fsize +
dlslot->e_sections[sec].s_pad)) {
bsz = dlslot->e_sections[sec].s_pad -
(secoff - dlslot->e_sections[sec].s_fsize);
if (bsz > dlslot->dl_bsz)
bsz = dlslot->dl_bsz;
memset(buf, 0, (len = bsz));
}
/*
* ...and if we haven't hit either of those cases,
* that's the end of the image.
*/
else {
return (0);
}
/*
* Advance the logical image pointer.
*/
dlslot->e_curpos += bsz;
if (dlslot->e_curpos >= (dlslot->e_sections[sec].s_loff +
dlslot->e_sections[sec].s_fsize +
dlslot->e_sections[sec].s_pad))
if (++dlslot->e_cursec >= dlslot->e_nsec)
return (0);
break;
case IMAGE_TYPE_AOUT:
bsz = dlslot->dl_bsz;
pos = dlslot->a_lseek;
len = 0;
total = dlslot->a_text;
if (pos < total) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = read(dlslot->ldfd,&buf[len],notdone);
} else {
outlen = read(dlslot->ldfd,&buf[len],bsz);
}
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}
total = total + dlslot->a_text_fill;
if ((bsz > 0) && (pos < total)) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = notdone;
} else {
outlen = bsz;
}
memset(&buf[len], 0, outlen);
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}
total = total + dlslot->a_data;
if ((bsz > 0) && (pos < total)) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = read(dlslot->ldfd,&buf[len],notdone);
} else {
outlen = read(dlslot->ldfd,&buf[len],bsz);
}
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}
total = total + dlslot->a_data_fill;
if ((bsz > 0) && (pos < total)) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = notdone;
} else {
outlen = bsz;
}
memset(&buf[len], 0, outlen);
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}
total = total + dlslot->a_bss;
if ((bsz > 0) && (pos < total)) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = notdone;
} else {
outlen = bsz;
}
memset(&buf[len], 0, outlen);
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}
total = total + dlslot->a_bss_fill;
if ((bsz > 0) && (pos < total)) {
notdone = total - pos;
if (notdone <= bsz) {
outlen = notdone;
} else {
outlen = bsz;
}
memset(&buf[len], 0, outlen);
len = len + outlen;
pos = pos + outlen;
bsz = bsz - outlen;
}