/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. 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.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
*
* @(#)mkboot.c 8.1 (Berkeley) 7/15/93
*/
#if 0
#ifndef lint
static char copyright[] =
"@(#) Copyright (c) 1990, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
int
putfile(char *from_file, int to)
{
struct exec ex;
char buf[2048];
int n, total;
int from, check_sum = 0;
struct hppa_lifload load;
Elf32_External_Ehdr elf_header;
Elf32_External_Phdr *elf_segments = NULL;
int i, header_count, memory_needed, elf_load_image_segment;
if ((from = open(from_file, O_RDONLY)) < 0)
err(1, "%s", from_file);
n = read(from, &ex, sizeof(ex));
if (n != sizeof(ex))
err(1, "%s: reading file header", from_file);
entry = ex.a_entry;
if (N_GETMAGIC(ex) == OMAGIC || N_GETMAGIC(ex) == NMAGIC)
entry += sizeof(ex);
else if (IS_ELF(*(Elf32_External_Ehdr *)&ex)) {
if (lseek(from, 0, SEEK_SET) < 0)
err(1, "lseek");
n = read(from, &elf_header, sizeof (elf_header));
if (n != sizeof (elf_header))
err(1, "%s: reading ELF header", from_file);
header_count = ELFGET16(elf_header.e_phnum);
memory_needed = header_count * sizeof (Elf32_External_Phdr);
elf_segments = malloc(memory_needed);
if (elf_segments == NULL)
err(1, "malloc");
if (lseek(from, ELFGET32(elf_header.e_phoff), SEEK_SET) < 0)
err(1, "lseek");
n = read(from, elf_segments, memory_needed);
if (n != memory_needed)
err(1, "%s: reading ELF segments", from_file);
elf_load_image_segment = -1;
for (i = 0; i < header_count; i++) {
if (ELFGET32(elf_segments[i].p_filesz) &&
ELFGET32(elf_segments[i].p_flags) & PF_X) {
if (elf_load_image_segment != -1)
errx(1, "%s: more than one ELF program "
"segment", from_file);
elf_load_image_segment = i;
}
}
if (elf_load_image_segment == -1)
errx(1, "%s: no suitable ELF program segment",
from_file);
entry = ELFGET32(elf_header.e_entry) +
ELFGET32(elf_segments[elf_load_image_segment].p_offset) -
ELFGET32(elf_segments[elf_load_image_segment].p_vaddr);
} else if (*(uint8_t *)&ex == 0x1f && ((uint8_t *)&ex)[1] == 0x8b) {
entry = 0;
} else
errx(1, "%s: bad magic number", from_file);
if (verbose)
warnx("wrote %d bytes of file \'%s\'", total, from_file);
total += sizeof(load);
/* insert the header */
lseek(to, -total, SEEK_CUR);
if (write(to, &load, sizeof(load)) != sizeof(load))
err(1, "%s", to_file);
lseek(to, total - sizeof(load), SEEK_CUR);
memset(buf, 0, sizeof(buf));
/* pad to int */
n = sizeof(int) - total % sizeof(int);
if (total % sizeof(int)) {
if (write(to, buf, n) != n)
err(1, "%s", to_file);
else
total += n;
}
/* pad to the blocksize */
n = sizeof(buf) - total % sizeof(buf);
if (n < sizeof(int)) {
n += sizeof(buf);
total += sizeof(buf);
} else
total += n;
/* TODO should pad here to the 65k boundary for tape boot */
if (verbose)
warnx("checksum is 0x%08x", -check_sum);
if (write(to, buf, n) != n)
err(1, "%s", to_file);
if (close(from) < 0)
err(1, "%s", from_file);
free(elf_segments);
return total;
}
int
cksum(int ck, int *p, int size)
{
/* we assume size is int-aligned */
for (size = (size + sizeof(int) - 1) / sizeof(int); size--; p++ )
ck += be32toh(*p);