xref: /illumos-gate/usr/src/tools/btxld/version.c (revision b59f980d)
10cc5983cSToomas Soome /*
20cc5983cSToomas Soome  * This file and its contents are supplied under the terms of the
30cc5983cSToomas Soome  * Common Development and Distribution License ("CDDL"), version 1.0.
40cc5983cSToomas Soome  * You may only use this file in accordance with the terms of version
50cc5983cSToomas Soome  * 1.0 of the CDDL.
60cc5983cSToomas Soome  *
70cc5983cSToomas Soome  * A full copy of the text of the CDDL should have accompanied this
80cc5983cSToomas Soome  * source.  A copy of the CDDL is also available via the Internet at
90cc5983cSToomas Soome  * http://www.illumos.org/license/CDDL.
100cc5983cSToomas Soome  */
110cc5983cSToomas Soome 
120cc5983cSToomas Soome /*
130cc5983cSToomas Soome  * Copyright 2016 Toomas Soome <tsoome@me.com>
140cc5983cSToomas Soome  */
150cc5983cSToomas Soome 
160cc5983cSToomas Soome #include <stdio.h>
170cc5983cSToomas Soome #include <sys/types.h>
180cc5983cSToomas Soome #include <sys/stat.h>
190cc5983cSToomas Soome #include <fcntl.h>
200cc5983cSToomas Soome #include <unistd.h>
210cc5983cSToomas Soome #include <sys/sysmacros.h>
220cc5983cSToomas Soome #include <sys/multiboot.h>
230cc5983cSToomas Soome 
240cc5983cSToomas Soome #include "bblk_einfo.h"
250cc5983cSToomas Soome #include "boot_utils.h"
260cc5983cSToomas Soome #include "mboot_extra.h"
270cc5983cSToomas Soome 
280cc5983cSToomas Soome /*
290cc5983cSToomas Soome  * Add version to loader bootblock file. The file should have fake
300cc5983cSToomas Soome  * multiboot header and version data will be added at the end of the file.
310cc5983cSToomas Soome  * MB header is fake in sense that this bootblock is *not* MB compatible,
320cc5983cSToomas Soome  * and MB header will only include load_addr and load_end_addr components.
330cc5983cSToomas Soome  * load_addr will be set to value 0 to indicate the beginning of the file
340cc5983cSToomas Soome  * and load_end_addr will be set to the size of the original file.
350cc5983cSToomas Soome  * The flags value in header must be exactly AOUT kludge.
360cc5983cSToomas Soome  *
370cc5983cSToomas Soome  * version data is aligned by 8 bytes and whole blootblock will be padded to
380cc5983cSToomas Soome  * 512B sector size.
390cc5983cSToomas Soome  *
400cc5983cSToomas Soome  * To use and verify version data, first find MB header, then load_end_addr
410cc5983cSToomas Soome  * will point to the end of the original file, aligned up by 8, is version
420cc5983cSToomas Soome  * data implemented as bblk einfo.
430cc5983cSToomas Soome  */
440cc5983cSToomas Soome 
450cc5983cSToomas Soome void
add_version(const char * ifile,const char * ofile,char * version)46*b59f980dSToomas Soome add_version(const char *ifile, const char *ofile, char *version)
470cc5983cSToomas Soome {
480cc5983cSToomas Soome 	int fd;
490cc5983cSToomas Soome 	int ret;
500cc5983cSToomas Soome 	uint32_t buf_size;
510cc5983cSToomas Soome 	uint32_t mboot_off;
520cc5983cSToomas Soome 	uint32_t extra;
530cc5983cSToomas Soome 	uint32_t avail_space;
540cc5983cSToomas Soome 	multiboot_header_t *mboot;
550cc5983cSToomas Soome 	struct stat sb;
560cc5983cSToomas Soome 	char *buf;
570cc5983cSToomas Soome 	bblk_hs_t hs;
580cc5983cSToomas Soome 
59*b59f980dSToomas Soome 	fd = open(ifile, O_RDONLY);
600cc5983cSToomas Soome 	if (fd == -1) {
610cc5983cSToomas Soome 		perror("open");
620cc5983cSToomas Soome 		return;
630cc5983cSToomas Soome 	}
640cc5983cSToomas Soome 	if (fstat(fd, &sb) == -1) {
650cc5983cSToomas Soome 		perror("fstat");
660cc5983cSToomas Soome 		close(fd);
670cc5983cSToomas Soome 		return;
680cc5983cSToomas Soome 	}
690cc5983cSToomas Soome 
700cc5983cSToomas Soome 	/*
710cc5983cSToomas Soome 	 * make sure we have enough space to append EINFO.
720cc5983cSToomas Soome 	 */
730cc5983cSToomas Soome 	buf_size = P2ROUNDUP(sb.st_size + SECTOR_SIZE, SECTOR_SIZE);
740cc5983cSToomas Soome 	buf = malloc(buf_size);
750cc5983cSToomas Soome 	if (buf == NULL) {
760cc5983cSToomas Soome 		perror("malloc");
770cc5983cSToomas Soome 		close(fd);
780cc5983cSToomas Soome 		return;
790cc5983cSToomas Soome 	}
800cc5983cSToomas Soome 
810cc5983cSToomas Soome 	/*
820cc5983cSToomas Soome 	 * read in whole file. we need to access MB header and einfo
830cc5983cSToomas Soome 	 * will create MD5 hash.
840cc5983cSToomas Soome 	 */
850cc5983cSToomas Soome 	ret = read(fd, buf, sb.st_size);
860cc5983cSToomas Soome 	if (ret != sb.st_size) {
870cc5983cSToomas Soome 		perror("read");
880cc5983cSToomas Soome 		free(buf);
890cc5983cSToomas Soome 		close(fd);
900cc5983cSToomas Soome 		return;
910cc5983cSToomas Soome 	}
920cc5983cSToomas Soome 	close(fd);
930cc5983cSToomas Soome 
940cc5983cSToomas Soome 	if (find_multiboot(buf, MBOOT_SCAN_SIZE, &mboot_off)
950cc5983cSToomas Soome 	    != BC_SUCCESS) {
960cc5983cSToomas Soome 		printf("Unable to find multiboot header\n");
970cc5983cSToomas Soome 		free(buf);
980cc5983cSToomas Soome 		return;
990cc5983cSToomas Soome 	}
1000cc5983cSToomas Soome 
1010cc5983cSToomas Soome 	mboot = (multiboot_header_t *)(buf + mboot_off);
1020cc5983cSToomas Soome 	mboot->load_addr = 0;
1030cc5983cSToomas Soome 	mboot->load_end_addr = sb.st_size;
1040cc5983cSToomas Soome 
1050cc5983cSToomas Soome 
1060cc5983cSToomas Soome 	hs.src_buf = (unsigned char *)buf;
1070cc5983cSToomas Soome 	hs.src_size = sb.st_size;
1080cc5983cSToomas Soome 
1090cc5983cSToomas Soome 	/*
1100cc5983cSToomas Soome 	 * this is location for EINFO data
1110cc5983cSToomas Soome 	 */
1120cc5983cSToomas Soome 	extra = P2ROUNDUP(sb.st_size, 8);
1130cc5983cSToomas Soome 	avail_space = buf_size - extra;
1140cc5983cSToomas Soome 	memset(buf+sb.st_size, 0, buf_size - sb.st_size);
1150cc5983cSToomas Soome 	add_einfo(buf + extra, version, &hs, avail_space);
1160cc5983cSToomas Soome 
117*b59f980dSToomas Soome 	fd = open(ofile, O_CREAT | O_WRONLY | O_TRUNC, 0644);
1180cc5983cSToomas Soome 	if (fd == -1) {
1190cc5983cSToomas Soome 		perror("open");
1200cc5983cSToomas Soome 		free(buf);
1210cc5983cSToomas Soome 		return;
1220cc5983cSToomas Soome 	}
1230cc5983cSToomas Soome 	ret = write(fd, buf, buf_size);
1240cc5983cSToomas Soome 	close(fd);
1250cc5983cSToomas Soome 	free(buf);
1260cc5983cSToomas Soome }
127