1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1999 Global Technology Associates, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 21 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 22 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD: stable/11/usr.sbin/kgzip/kgzld.c 330449 2018-03-05 07:26:05Z eadler $ 29 */ 30 31#include <sys/types.h> 32#include <sys/endian.h> 33#include <sys/wait.h> 34 35#include <err.h> 36#include <fcntl.h> 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40#include <unistd.h> 41 42#include "aouthdr.h" 43#include "elfhdr.h" 44#include "kgzip.h" 45 46#define align(x, y) (((x) + (y) - 1) & ~((y) - 1)) 47 48/* 49 * Link KGZ file and loader. 50 */ 51void 52kgzld(struct kgz_hdr * kh, const char *f1, const char *f2) 53{ 54 char addr[16]; 55 struct iodesc idi; 56 pid_t pid; 57 size_t n; 58 int status; 59 60 if (strcmp(kh->ident, "KGZ")) { 61 if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1) 62 err(1, "%s", idi.fname); 63 if (!format) { 64 union { 65 struct exec ex; 66 Elf32_Ehdr ee; 67 } hdr; 68 n = xread(&idi, &hdr, sizeof(hdr), 0); 69 if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee)) 70 format = F_ELF; 71 else if (n >= sizeof(hdr.ex) && 72 N_GETMAGIC(hdr.ex) == OMAGIC) 73 format = F_AOUT; 74 if (!format) 75 errx(1, "%s: Format not supported", idi.fname); 76 } 77 n = xread(&idi, kh, sizeof(*kh), 78 format == F_AOUT ? sizeof(struct kgz_aouthdr0) 79 : sizeof(struct kgz_elfhdr)); 80 xclose(&idi); 81 if (n != sizeof(*kh) || strcmp(kh->ident, "KGZ")) 82 errx(1, "%s: Invalid format", idi.fname); 83 } 84 sprintf(addr, "%#x", align(kh->dload + kh->dsize, 0x1000)); 85 switch (pid = fork()) { 86 case -1: 87 err(1, NULL); 88 case 0: 89 if (format == F_AOUT) 90 execlp("ld", "ld", "-aout", "-Z", "-T", addr, "-o", f2, 91 loader, f1, (char *)NULL); 92 else 93 execlp("ld", "ld", "-Ttext", addr, "-o", f2, loader, f1, 94 (char *)NULL); 95 warn(NULL); 96 _exit(1); 97 default: 98 if ((pid = waitpid(pid, &status, 0)) == -1) 99 err(1, NULL); 100 if (WIFSIGNALED(status) || WEXITSTATUS(status)) 101 exit(1); 102 } 103} 104