xref: /titanic_52/usr/src/tools/btxld/version.c (revision 150a695268c611611ebabadb00df2a16f2f81fa7)
1*150a6952SToomas Soome /*
2*150a6952SToomas Soome  * This file and its contents are supplied under the terms of the
3*150a6952SToomas Soome  * Common Development and Distribution License ("CDDL"), version 1.0.
4*150a6952SToomas Soome  * You may only use this file in accordance with the terms of version
5*150a6952SToomas Soome  * 1.0 of the CDDL.
6*150a6952SToomas Soome  *
7*150a6952SToomas Soome  * A full copy of the text of the CDDL should have accompanied this
8*150a6952SToomas Soome  * source.  A copy of the CDDL is also available via the Internet at
9*150a6952SToomas Soome  * http://www.illumos.org/license/CDDL.
10*150a6952SToomas Soome  */
11*150a6952SToomas Soome 
12*150a6952SToomas Soome /*
13*150a6952SToomas Soome  * Copyright 2016 Toomas Soome <tsoome@me.com>
14*150a6952SToomas Soome  */
15*150a6952SToomas Soome 
16*150a6952SToomas Soome #include <stdio.h>
17*150a6952SToomas Soome #include <sys/types.h>
18*150a6952SToomas Soome #include <sys/stat.h>
19*150a6952SToomas Soome #include <fcntl.h>
20*150a6952SToomas Soome #include <unistd.h>
21*150a6952SToomas Soome #include <sys/sysmacros.h>
22*150a6952SToomas Soome #include <sys/multiboot.h>
23*150a6952SToomas Soome 
24*150a6952SToomas Soome #include "bblk_einfo.h"
25*150a6952SToomas Soome #include "boot_utils.h"
26*150a6952SToomas Soome #include "mboot_extra.h"
27*150a6952SToomas Soome 
28*150a6952SToomas Soome /*
29*150a6952SToomas Soome  * Add version to loader bootblock file. The file should have fake
30*150a6952SToomas Soome  * multiboot header and version data will be added at the end of the file.
31*150a6952SToomas Soome  * MB header is fake in sense that this bootblock is *not* MB compatible,
32*150a6952SToomas Soome  * and MB header will only include load_addr and load_end_addr components.
33*150a6952SToomas Soome  * load_addr will be set to value 0 to indicate the beginning of the file
34*150a6952SToomas Soome  * and load_end_addr will be set to the size of the original file.
35*150a6952SToomas Soome  * The flags value in header must be exactly AOUT kludge.
36*150a6952SToomas Soome  *
37*150a6952SToomas Soome  * version data is aligned by 8 bytes and whole blootblock will be padded to
38*150a6952SToomas Soome  * 512B sector size.
39*150a6952SToomas Soome  *
40*150a6952SToomas Soome  * To use and verify version data, first find MB header, then load_end_addr
41*150a6952SToomas Soome  * will point to the end of the original file, aligned up by 8, is version
42*150a6952SToomas Soome  * data implemented as bblk einfo.
43*150a6952SToomas Soome  */
44*150a6952SToomas Soome 
45*150a6952SToomas Soome void
46*150a6952SToomas Soome add_version(char *file, char *version)
47*150a6952SToomas Soome {
48*150a6952SToomas Soome 	int fd;
49*150a6952SToomas Soome 	int ret;
50*150a6952SToomas Soome 	uint32_t buf_size;
51*150a6952SToomas Soome 	uint32_t mboot_off;
52*150a6952SToomas Soome 	uint32_t extra;
53*150a6952SToomas Soome 	uint32_t avail_space;
54*150a6952SToomas Soome 	multiboot_header_t *mboot;
55*150a6952SToomas Soome 	struct stat sb;
56*150a6952SToomas Soome 	char *buf;
57*150a6952SToomas Soome 	bblk_hs_t hs;
58*150a6952SToomas Soome 
59*150a6952SToomas Soome 	fd = open(file, O_RDONLY);
60*150a6952SToomas Soome 	if (fd == -1) {
61*150a6952SToomas Soome 		perror("open");
62*150a6952SToomas Soome 		return;
63*150a6952SToomas Soome 	}
64*150a6952SToomas Soome 	if (fstat(fd, &sb) == -1) {
65*150a6952SToomas Soome 		perror("fstat");
66*150a6952SToomas Soome 		close(fd);
67*150a6952SToomas Soome 		return;
68*150a6952SToomas Soome 	}
69*150a6952SToomas Soome 
70*150a6952SToomas Soome 	/*
71*150a6952SToomas Soome 	 * make sure we have enough space to append EINFO.
72*150a6952SToomas Soome 	 */
73*150a6952SToomas Soome 	buf_size = P2ROUNDUP(sb.st_size + SECTOR_SIZE, SECTOR_SIZE);
74*150a6952SToomas Soome 	buf = malloc(buf_size);
75*150a6952SToomas Soome 	if (buf == NULL) {
76*150a6952SToomas Soome 		perror("malloc");
77*150a6952SToomas Soome 		close(fd);
78*150a6952SToomas Soome 		return;
79*150a6952SToomas Soome 	}
80*150a6952SToomas Soome 
81*150a6952SToomas Soome 	/*
82*150a6952SToomas Soome 	 * read in whole file. we need to access MB header and einfo
83*150a6952SToomas Soome 	 * will create MD5 hash.
84*150a6952SToomas Soome 	 */
85*150a6952SToomas Soome 	ret = read(fd, buf, sb.st_size);
86*150a6952SToomas Soome 	if (ret != sb.st_size) {
87*150a6952SToomas Soome 		perror("read");
88*150a6952SToomas Soome 		free(buf);
89*150a6952SToomas Soome 		close(fd);
90*150a6952SToomas Soome 		return;
91*150a6952SToomas Soome 	}
92*150a6952SToomas Soome 	close(fd);
93*150a6952SToomas Soome 
94*150a6952SToomas Soome 	if (find_multiboot(buf, MBOOT_SCAN_SIZE, &mboot_off)
95*150a6952SToomas Soome 	    != BC_SUCCESS) {
96*150a6952SToomas Soome 		printf("Unable to find multiboot header\n");
97*150a6952SToomas Soome 		free(buf);
98*150a6952SToomas Soome 		return;
99*150a6952SToomas Soome 	}
100*150a6952SToomas Soome 
101*150a6952SToomas Soome 	mboot = (multiboot_header_t *)(buf + mboot_off);
102*150a6952SToomas Soome 	mboot->load_addr = 0;
103*150a6952SToomas Soome 	mboot->load_end_addr = sb.st_size;
104*150a6952SToomas Soome 
105*150a6952SToomas Soome 
106*150a6952SToomas Soome 	hs.src_buf = (unsigned char *)buf;
107*150a6952SToomas Soome 	hs.src_size = sb.st_size;
108*150a6952SToomas Soome 
109*150a6952SToomas Soome 	/*
110*150a6952SToomas Soome 	 * this is location for EINFO data
111*150a6952SToomas Soome 	 */
112*150a6952SToomas Soome 	extra = P2ROUNDUP(sb.st_size, 8);
113*150a6952SToomas Soome 	avail_space = buf_size - extra;
114*150a6952SToomas Soome 	memset(buf+sb.st_size, 0, buf_size - sb.st_size);
115*150a6952SToomas Soome 	add_einfo(buf + extra, version, &hs, avail_space);
116*150a6952SToomas Soome 
117*150a6952SToomas Soome 	fd = open(file, O_WRONLY | O_TRUNC);
118*150a6952SToomas Soome 	if (fd == -1) {
119*150a6952SToomas Soome 		perror("open");
120*150a6952SToomas Soome 		free(buf);
121*150a6952SToomas Soome 		return;
122*150a6952SToomas Soome 	}
123*150a6952SToomas Soome 	ret = write(fd, buf, buf_size);
124*150a6952SToomas Soome 	close(fd);
125*150a6952SToomas Soome 	free(buf);
126*150a6952SToomas Soome }
127