#!/usr/bin/perl -w # ********************************************************** # Copyright 2004 VMware, Inc. All rights reserved. # -- VMware Confidential # ********************************************************** use strict; no strict "refs"; use Getopt::Long; my $execname = $0; my (%shared_hash, %peer_hash, %scb_hash, %shared_file_hash, %peer_file_hash, %scb_file_hash); my @vcpu_padding; # [0] <-> 32 bit, [1] <-> 64-bit my $error_count = 0; my $order = 0; my $page_size = 4096; my ($arg_vmm32_path, $arg_vmm64_path, $arg_output_path, $arg_nm); sub generating_64bit() { return $arg_output_path =~ m/vmm64/; } sub generate_overlay_head(*) { local *FP = shift; printf(FP <= $string_length) { die("'$execname: $symbol' length is greater than $string_length\n"); } for ($i = 0; $i < length($symbol); ++$i) { my $ch = substr($symbol, $i, 1); printf(FP " BYTE(%3d); /* %1s */ \n", ord($ch), $ch); } while ($i < $string_length) { printf(FP " BYTE(0);\n"); ++$i; } printf(FP "\n"); printf(FP " LONG($symbol - __%s_start);\n", $sect_name); my ($def_order, $def_size, $def_kind) = split(/:/, $hash->{$symbol}); printf(FP " LONG($def_size); /* sizeof */\n"); } printf(FP " }\n"); } sub generate_scb_references($) { # return ; # REMOVE THIS my $file = (shift) . "/callbacks.extern"; open(FP, ">$file") || die("Unable to create '$file'\n"); foreach my $symbol (keys %{scb_hash}) { my ($def_order, $def_size, $def_kind) = split(/:/, $scb_hash{$symbol}); if ($def_kind == 3 || (generating_64bit() && ($def_kind & 2)) || (!generating_64bit() && ($def_kind & 1))) { printf(FP "EXTERN($symbol)\n"); } } } sub generate_overlay($) { my $file = (shift) . "/overlay.ld"; open(OVERLAY, ">$file") || die("Unable to create '$file'\n"); generate_overlay_head(*OVERLAY{IO}); generate_overlay_metadata(*OVERLAY{IO}, "shared", \%shared_hash); generate_overlay_metadata(*OVERLAY{IO}, "peer", \%peer_hash); generate_overlay_tail(*OVERLAY{IO}); close(OVERLAY); } sub read_symbols($$$$) { my $symfile = shift; my $symbol_hash = shift; my $file_hash = shift; my $symfile_kind = shift; # 1 -> 32 bit symbols; 2 -> 64 bit symbols my ($sym_name, $sym_size, $sym_objfile); open(INPUT, "<$symfile") || die("Unable to open '$symfile'\n"); LINE: while () { chop; if (/^(\d+)$/) { if (!defined($vcpu_padding[$symfile_kind - 1])) { $vcpu_padding[$symfile_kind - 1] = int($1); } else { die("vcpu padding already defined as " . "'%d'. New value '$1' illegal\n", $vcpu_padding[$symfile_kind - 1]); } } else { ($sym_name, $sym_size, $sym_objfile) = split(/:/); $sym_size = hex($sym_size); if (defined($symbol_hash->{$sym_name})) { # Symbol already defined. # Make sure: # - not defined already in the current vmm size # - size is the same my ($def_order, $def_size, $def_kind) = split(/:/, $symbol_hash->{$sym_name}); $def_kind = hex($def_kind); if ($def_kind & $symfile_kind) { printf(STDERR "$execname: " . "symbol '$sym_name' multiply defined in '$symfile'\n"); $error_count++; } if ($def_size != $sym_size) { printf(STDERR "$execname: " . "symbol '$sym_name' has size '$def_size'; " . "new size '$sym_size' from '$symfile' does not match \n"); $error_count++; next LINE; } $def_kind |= $symfile_kind; # incl bit to denote symfile $symbol_hash->{$sym_name} = join(':', $def_order, $def_size, $def_kind); if ($file_hash->{$sym_name} ne $sym_objfile) { $file_hash->{$sym_name} = join(':', $file_hash->{$sym_name}, $sym_objfile); } } else { $symbol_hash->{$sym_name} = join(':', $order, $sym_size, $symfile_kind); $file_hash->{$sym_name} = $sym_objfile; } ++$order; } } close(INPUT); } sub validate_padding() { # Check that at least one of the vcpu padding sizes was defined. if (!defined($vcpu_padding[0]) && !defined($vcpu_padding[1])) { die("No vcpu padding was specified\n"); } if (!defined($vcpu_padding[0])) { warn("32-bit VCPU padding not defined\n"); } if (!defined($vcpu_padding[1])) { warn("64-bit VCPU padding not defined; see PR46756\n"); } if (defined($vcpu_padding[0]) && defined($vcpu_padding[1]) && ($vcpu_padding[0] != $vcpu_padding[1])) { die("32- and 64-bit vcpu paddings do not match (%d -vs- %d)\n", $vcpu_padding[0], $vcpu_padding[1]); } } sub alignment($$) { my $symbol = shift; my $def_size = shift; my $align = $def_size > 4 ? 4 : $def_size; if ($align & ($align - 1)) { die("Alignment for '$symbol' is not a power of 2\n"); } return $align; } sub allocate_symbol(*$$$) { local *FP = shift; my $symbol = shift; my $hash = shift; my $file_hash = shift; my ($i, $sym_size, $sym_defn); my ($def_order, $def_size, $def_kind) = split(/:/, $hash->{$symbol}); printf(FP "\t. = ALIGN(%d);\n" . "\t%-32s /* [%2s %2s] %s */\n" . "\t. += %d;\n", alignment($symbol, $def_size), "$symbol = .;", $def_kind & 1 ? "32" : "", $def_kind & 2 ? "64" : "", defined($file_hash->{$symbol}) ? "$file_hash->{$symbol}" : "