148905Srnordier/* 248905Srnordier * Copyright (c) 1999 Global Technology Associates, Inc. 348905Srnordier * All rights reserved. 448905Srnordier * 548905Srnordier * Redistribution and use in source and binary forms, with or without 648905Srnordier * modification, are permitted provided that the following conditions 748905Srnordier * are met: 848905Srnordier * 1. Redistributions of source code must retain the above copyright 948905Srnordier * notice, this list of conditions and the following disclaimer. 1048905Srnordier * 2. Redistributions in binary form must reproduce the above copyright 1148905Srnordier * notice, this list of conditions and the following disclaimer in the 1248905Srnordier * documentation and/or other materials provided with the distribution. 1348905Srnordier * 1448905Srnordier * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND 1548905Srnordier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1648905Srnordier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1748905Srnordier * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 1848905Srnordier * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 1948905Srnordier * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 2048905Srnordier * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 2148905Srnordier * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2248905Srnordier * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 2348905Srnordier * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 2448905Srnordier * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2548905Srnordier * 2650479Speter * $FreeBSD$ 2748905Srnordier */ 2848905Srnordier 2948905Srnordier#include <sys/types.h> 30130927Sobrien#include <sys/endian.h> 3148905Srnordier#include <sys/wait.h> 3248905Srnordier 3348905Srnordier#include <err.h> 3448905Srnordier#include <fcntl.h> 3548905Srnordier#include <stdio.h> 3648905Srnordier#include <stdlib.h> 3748905Srnordier#include <string.h> 3848905Srnordier#include <unistd.h> 3948905Srnordier 4068313Srnordier#include "aouthdr.h" 4148905Srnordier#include "elfhdr.h" 4248905Srnordier#include "kgzip.h" 4348905Srnordier 4448905Srnordier#define align(x, y) (((x) + (y) - 1) & ~((y) - 1)) 4548905Srnordier 4648905Srnordier/* 4748905Srnordier * Link KGZ file and loader. 4848905Srnordier */ 4948905Srnordiervoid 5048905Srnordierkgzld(struct kgz_hdr * kh, const char *f1, const char *f2) 5148905Srnordier{ 5248905Srnordier char addr[16]; 5348905Srnordier struct iodesc idi; 5448905Srnordier pid_t pid; 5548905Srnordier size_t n; 5648905Srnordier int status; 5748905Srnordier 5848905Srnordier if (strcmp(kh->ident, "KGZ")) { 5948905Srnordier if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1) 6048905Srnordier err(1, "%s", idi.fname); 6168313Srnordier if (!format) { 6268313Srnordier union { 6368313Srnordier struct exec ex; 6468313Srnordier Elf32_Ehdr ee; 6568313Srnordier } hdr; 6668313Srnordier n = xread(&idi, &hdr, sizeof(hdr), 0); 6768313Srnordier if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee)) 6868313Srnordier format = F_ELF; 6968313Srnordier else if (n >= sizeof(hdr.ex) && 7068313Srnordier N_GETMAGIC(hdr.ex) == OMAGIC) 7168313Srnordier format = F_AOUT; 7268313Srnordier if (!format) 7368313Srnordier errx(1, "%s: Format not supported", idi.fname); 7468313Srnordier } 7568313Srnordier n = xread(&idi, kh, sizeof(*kh), 7668313Srnordier format == F_AOUT ? sizeof(struct kgz_aouthdr0) 7768313Srnordier : sizeof(struct kgz_elfhdr)); 7848905Srnordier xclose(&idi); 7948905Srnordier if (n != sizeof(*kh) || strcmp(kh->ident, "KGZ")) 8048905Srnordier errx(1, "%s: Invalid format", idi.fname); 8148905Srnordier } 8248905Srnordier sprintf(addr, "%#x", align(kh->dload + kh->dsize, 0x1000)); 8348905Srnordier switch (pid = fork()) { 8448905Srnordier case -1: 8548905Srnordier err(1, NULL); 8648905Srnordier case 0: 8768313Srnordier if (format == F_AOUT) 8868313Srnordier execlp("ld", "ld", "-aout", "-Z", "-T", addr, "-o", f2, 8979452Sbrian loader, f1, (char *)NULL); 9068313Srnordier else 9168313Srnordier execlp("ld", "ld", "-Ttext", addr, "-o", f2, loader, f1, 9279452Sbrian (char *)NULL); 9348905Srnordier warn(NULL); 9448905Srnordier _exit(1); 9548905Srnordier default: 9648905Srnordier if ((pid = waitpid(pid, &status, 0)) == -1) 9748905Srnordier err(1, NULL); 9848905Srnordier if (WIFSIGNALED(status) || WEXITSTATUS(status)) 9948905Srnordier exit(1); 10048905Srnordier } 10148905Srnordier} 102