linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pantelis Antoniou <panto@intracom.gr>
To: linux-kernel@vger.kernel.org
Subject: Re: [RFC] Standard way of generating assembler offsets
Date: Tue, 09 Oct 2001 10:38:52 +0300	[thread overview]
Message-ID: <3BC2A98C.A57EA360@intracom.gr> (raw)
In-Reply-To: <28136.1002196028@ocs3.intra.ocs.com.au> <3BC1735F.41CBF5C1@intracom.gr>  <3BC1E294.1A4FB12D@mvista.com> <1002563771.21079.3.camel@keller> <3BC1F7D6.E84D617B@mvista.com>

[-- Attachment #1: Type: text/plain, Size: 2041 bytes --]

george anzinger wrote:
> 
> Georg Nikodym wrote:
> >
> > At the risk of sticking my foot in it, is there something wrong with the
> > ANSI C offsetof() macro, defined in <stddef.h>?
> >
> > --Georg
> No, and it could have been (and was) written prio to ANSI C defining
> it.  Something like:
> 
> #define offsetof(x, instruct) &((struct instruct *)0)->x
> 
> The issues that CPP resolves have to deal with the following sort of
> structure:
> 
> struct instruct {
>         struct foo * bar;
> #ifdef CONFIG_OPTION_DIDDLE
>         int diddle_flag;
>         int diddle_array[CONFIG_DIDDLE_SIZE];
> #endif
>         int x;
> }
> 
> Or for the simple need for a constant:
> 
> #define Const (CONFIG_DIDDLE_SIZE * sizeof(int))
> 
> Of course you could have any number of constant operators in the
> expression.  Note also, that the array in the structure above is defined
> by a CONFIG symbol.  This could also involve math, i.e.:
> 
> #define CONFIG_DIDDLE_SIZE CLOCK_RATE / HZ
> 
> and so on.  All in all, it best to let CPP do what it does best and
> scarf up the result:
> 
> #define GENERATE_CONSTANT(name,c) printf(#name " equ %d\n",c)
> 
> then:
> 
> GENERATE_CONSTANT(diddle_size,CONFIG_DIDDLE_SIZE);
> 
> In the code we did, we put all the GENERATE macros in a .h file.  The
> the code looked like:
> 
> #include.... all the headers needed....
> 
> #include <generate.h>
> 
> GENERATE....  all the generate macro calls...
> 
> } // all done (assumes that the "main(){" is in the generate.h file)
> 
> This whole mess was included as comments in the asm file.  The make rule
> then used a sed script to extract it, compile and run it to produce a
> new header file which the asm source included outside of the above
> stuff.
> 
> George

My script already handles that, everything is first passed through
CPP and the member offset are varied correctly according to any
compilation options.

I included the script and the results of two runs.

1. ./h2inc tst.h >tst.inc

2. ./h2inc --cflags="-DSHOW_HIDDEN -I./" >tst-hidden.inc

Regards

[-- Attachment #2: h2inc --]
[-- Type: text/plain, Size: 18360 bytes --]

#!/usr/bin/perl -w

use integer;
use Getopt::Long;
use File::Basename;
use File::stat;

my $CC       = "cc";
my $CFLAGS   = "-I./";
my $CPPFLAGS = "-E -dD";
my $OBJCOPY  = "objcopy";
my $OBJFLAGS = "-O binary";

sub find_32bit_type;
sub target_endianess;
sub alligned_type_size;
sub base_type_size;
sub members_offset;
sub tmpfile;
sub inputfile;
sub decode_type;
sub decode_member;
sub find_complex_member_name;
sub find_matching_brace;

$Getopt::Long::ignorecase = 0;	# Don't ignore case

my @filelist = ();

GetOptions	(
	"cc=s" 			=> \$CC,
	"cflags=s" 		=> \$CFLAGS,
	"cppflags=s" 	=> \$CPPFLAGS,
	"objcopy=s" 	=> \$OBJCOPY,
	"objflags=s" 	=> \$OBJFLAGS
			);

`$CC 2>/dev/null -v`;
die "Compiler is not present", if $? != 0;

my $u32 		= &find_32bit_type();
my $endianess 	= &target_endianess($u32);

for ($i = 0; $i <= $#ARGV; $i++) {
	$_ = $ARGV[$i];
	# print STDERR "file: $_\n";
	push @filelist, $_;
}

$#filelist >= 0 || die "Filename missing\n";

my %members  = ();
my %typedefs = ();
my %structs  = ();
my %unions   = ();

my %ilist = ();	# hash of included files
my $ilist;

my $defines;

foreach $f (@filelist) {

	$f = basename($f);

	%ilist = ();
	undef $ilist;

	$defines = "";

	&inputfile($f);

	my @defines = split(/\n/, $defines);

	my $incfile = $f;
	$incfile =~ s/\.h$/.inc/g;
	$incfile =~ s/\S*\/(\S+\.inc)/$1/g;
	my $incfiledef = "_" . uc($incfile);
	$incfiledef =~ s/\./_/g;

	print "#ifndef $incfiledef\n";
	print "#define $incfiledef\n\n";

	if (defined ($ilist)) {
		my $if;
		foreach $if (split /\s/, $ilist) {
			$if =~ s/\.h$/.inc/g;
			$if =~ s/\S*\/(\S+\.inc)/$1/g;
			$if = basename($if);
			print "#include \"$if\"\n";
		}
		print "\n";
	}

	my @offsets;
	my $b;
	my $i;
	my $j;
	my $k;
	foreach $b (sort keys %members) {
		my @m = split /\s/, $members{$b};
		my $m;
		print "/****************************************************************\n\n";
		print "\tOffsets for $b\n\n";
		print "****************************************************************/\n\n";

		my $size_define;
		my $complete_type;

		if ($typedefs{$b}) {
			$complete_type = $b;
			$size_define = $b . "_SIZE";
		} elsif ($structs{$b}) {
			$complete_type = "struct $b";
			$size_define = "struct_" . $b . "_SIZE";
		} elsif ($unions{$b}) {
			$complete_type = "union $b";
			$size_define = "union_" . $b . "_SIZE";
		} else { die; }

		@offsets = &members_offset($endianess, $u32, "#include \"$f\"\n", $complete_type, \@m);

		$j = 0;
		foreach (@offsets) {
			my $cm = $m[$j++];
			my @cm = split(/\./, $cm);
			for ($k = 0; $k <= $#defines; $k++) {
				my @tt = split(/\s+/, $defines[$k]);
				if (defined($tt[2]) && $tt[2] eq $cm) {
					# print STDERR "define alias found for $cm\n";
					$defines[$k] = "/* $tt[1] removed as an alias for $cm */";
					@cm = ($tt[1]);
					last;
				}
			}
			$cm = join('_', @cm);
			printf("#define %-30s %3d\n", $cm, $_);
		}

		printf("#define %-30s %3d\n", $size_define, &base_type_size($endianess, $u32, "#include \"$f\"\n", $complete_type));

		print "\n";
	}

	$defines = join("\n", @defines);

	if ($defines ne "") {
		print "/****************************************************************\n\n";
		print "\tSimple defines list \n\n";
		print "****************************************************************/\n\n";
		print "$defines\n\n";
	}

	print "#endif\n";

}

sub inputfile {
	my $file = shift(@_);
	$file = basename($file);
	my @wf = ();	# whole file
	my $wf = '';
	my $size;
	my $align;

	# print STDERR "Processing : $file\n";

	my $tmp = &tmpfile();
	my $tmp_c = $tmp . ".c";
	my $tmp_o = $tmp . ".o";

	local $SIG{'INT'} =
		sub {
			unlink $tmp_c;
			unlink $tmp_o;
			die $_[0];
		};
	
	open(TMPFILE, ">$tmp_c") || die;
	print TMPFILE "#include \"$file\"\n";
	close(TMPFILE);
	# first verify that the header file is correct
	`$CC $CFLAGS -c $tmp_c -o $tmp_o`; 
	if ($? != 0) {
		# try system wide include
		open(TMPFILE, ">$tmp_c") || die;
		print TMPFILE "#include \<$file\>\n";
		close(TMPFILE);
		# first verify that the header file is correct
		`$CC $CFLAGS -c $tmp_c -o $tmp_o`; die, if ($? != 0);
	}
	unlink $tmp_o;	# remove object file

	# open(LOGFILE, ">log.i") || die;

	# print LOGFILE "$CC $CFLAGS $CPPFLAGS $tmp_c |\n";

	open(CPPPIPE, "$CC $CFLAGS $CPPFLAGS $tmp_c |") || die;

	$wf = "";
	my $cf = "";	# current file - only output for current file 

	my $last;
	my $lll;

	while (<CPPPIPE>) {
		# print LOGFILE $_;
		$lll = $_;
		chop;
		if (s/\\$//) {
			$_ .= <CPPPIPE>; redo;
		}	# check for escape at the end of line
		$last = $_;
		my $ll = $_;
		if (! /\s*\#\s*/) {
			if (basename($cf) eq basename($file)) {
				$wf .= "$_\n";
			}
			next;
		}
		# print STDERR "\$\_='$_'\n";
		# print STDERR "o: \$\_='$_', \$\`='$`', \$\&='$&', \$\'='$'\n";
		if (/\s+[0-9]+\s*\"([^\"].*)\"/) {
			# print STDERR "$cf - $1\n";
			my $c = basename($1);
			if (!defined($ilist{$c})) {
				next, if ($c eq basename($tmp_c));				# do not add the dummy 
				if ($c ne basename($file) &&
					basename($cf) eq basename($file)) { # do not add self, and only directly included
					# print STDERR "$ll: $1\n";	
					$ilist{$c} = 1;
					if (defined($ilist)) {
						$ilist .= " $c";
					} else {
						$ilist = $c;
					}
				}
			}
			$cf = basename($1);
		} elsif (/\s*define\s*([a-zA-Z_][a-zA-Z0-9_]*)/) {
			# $_ = $';
			next, if ($cf ne $file);
			# print STDERR "\$lll='$lll'\n\$last='$last'\n\$\_='$_'\n\$\`='$`'\n\$\&='$&'\n\$\'='$'\n";
			my $defname = $1;
			next, if (/\(.*\)/);	# ignore arguments
			$_ = $';
			if (/\S+.*$/) {
				my $what = $&;
				# next, if ($what =~ /[()]/);	# only simple defines pass
				# $defines .= "#define $defname $1\n";
				# print STDERR "1-> '$defname' '$what'\n";
				$defines .= sprintf("#define %-30s %s\n", $defname, $what);
			} else {
				# print STDERR "2-> $defname\n";
				$defines .= sprintf("#define %-30s\n", $defname);
			}
		} else {
			# print STDERR "$_";
		}
	}

	# close(LOGFILE);

	# print STDERR "FILE:\n" . $wf ."FEND:\n";
	$wf =~ s/([*;,.!~{}()+\-\\\/\[\]])/ $1 /gsx;	# add spaces
	$wf =~ s/\s+/ /gsx;
	# print STDERR $wf;
	@wf = split /\s/,  $wf;

	$i  = 0;
	OUTTER: while ($i < ($#wf + 1)) {
		# print STDERR "$i: '$wf[$i]'\n";
		if ($wf[$i] eq "typedef" && $wf[$i+1] eq "struct") {
			&decode_type(\@wf, \$i);
		} elsif ($wf[$i] eq "typedef" && $wf[$i+1] eq "union") {
			&decode_type(\@wf, \$i);
		} elsif ($wf[$i] eq "struct") {
			&decode_type(\@wf, \$i);
		} elsif ($wf[$i] eq "union") {
			&decode_type(\@wf, \$i);
		} else {
			$i++;
		}
	}
	close CPPPIPE;

	unlink $tmp_c;

	local $SIG{'INT'} = 'DEFAULT';

	return 1;
}

sub decode_member {
	my $wf = shift(@_);	# reference to the whole body of the file
	my $ms = shift(@_);	# start of member definition
	my $me = shift(@_);	# end of member definition
	my $ii;
	my $i;
	my $n;

	# decode right to left
	$i = $me;
	$i--, if ($$wf[$i] eq ";");
	while ($$wf[$i] eq "]") {	# array definition, find match 
		# print STDERR "'$$wf[$i]'\n";
		$n = 1;
		do {
			$i--;
			# print STDERR "'$$wf[$i]'\n";
			$n++, if ($$wf[$i] eq "]");
			$n--, if ($$wf[$i] eq "[");
		} while ($n > 0 || $$wf[$i] ne "[");
		$i--;
	}
	while ($$wf[$i] eq ")") {	# function pointer definition, find match 
		$n = 1;
		$ii = $i;
		# print STDERR "'$$wf[$ii]'\n";
		do {
			$ii--;
			# print STDERR "'$$wf[$ii]'\n";
			$n++, if ($$wf[$ii] eq ")");
			$n--, if ($$wf[$ii] eq "(");
		} while ($n > 0 || $$wf[$ii] ne "(");
		# now check if next token is a pointer then we've found it
		# print STDERR "i=$i, ii=$ii, '" . $$wf[$ii] . "' '" . $$wf[$ii+1] . "' '" . $$wf[$ii+2] . "'\n";
		if ($i - $ii == 3 && $$wf[$ii+1] eq "*") {	# found it!
			$i = $ii + 2;
		} else {
			$i = $ii - 1;
		}
	}
	# print STDERR "found; $$wf[$i]\n";
	return $$wf[$i];
}

sub find_complex_member_name {
	my $wf   = shift(@_);	# reference to the whole body of the file
	my $k    = shift(@_);	# start of member definition
	my $last = shift(@_);	# end of member definition

	my $ct = $$wf[$k];
	my $ccs = $k + 2;
	my $n = 0;
	do {
		$k++;
		$n++, if ($$wf[$k] eq "{");
		$n--, if ($$wf[$k] eq "}");
	} while ($n > 0);
	my $cce = $k;
	$k++;
	my $cs = $k;
	$k++, while ($$wf[$k] ne ";");
	my $ce = $k;
	$k++;
	my $cn = &decode_member($wf, $cs, $ce);
	return $cn;
}

sub find_matching_brace {
	my $wf   = shift(@_);	# reference to the whole body of the file
	my $k    = shift(@_);	# start of member definition
	my $last = shift(@_);	# end of member definition

	my $n = 0;
	do {
		$k++;
		$n++, if ($$wf[$k] eq "{");
		$n--, if ($$wf[$k] eq "}");
	} while ($n > 0);
	$k++;
	$k++, while ($$wf[$k] ne ";");
	$k++;
	return $k;
}

sub get_next_type_name {
}

sub decode_type {
	my $wf = shift(@_);	# reference to the whole body of the file
	my $i  = shift(@_);	# reference to the token index at the file
	my $n = 0;			# nesting level
	my $k;
	my $j;
	my $anchor;
	my $first_brace;
	my $last_brace;
	my $trailer;
	my @result = ();

	$anchor = $$i;		# keep this for later
	# now find the brace
	$j = $anchor;
	# first find opening brace or terminating semicolon
	$j++, while ($$wf[$j] ne "{" && $$wf[$j] ne ";");

	if ($$wf[$j] eq ";") {	# not a structure definition
		$$i = $j + 1;
		return "";
	}
	$first_brace = $j;

	$n = 1;
	do {
		$j++;
		$n++, if ($$wf[$j] eq "{");
		$n--, if ($$wf[$j] eq "}");
	} while ($n > 0 || $$wf[$j] ne "}");

	$last_brace = $j;

	# find terminating semicolon
	$j++, while ($$wf[$j] ne ";");

	my $is_typedef = $$wf[$anchor] eq "typedef";
	my $is_struct  = $$wf[$anchor] eq "struct";
	my $is_union   = $$wf[$anchor] eq "union";
	my $is_declaration = 0;
	my $base_type;

	if ($is_typedef) {
		my $ii = $j - 1;	# remove semicolon
		# print STDERR "is_typedef\n";
		# print STDERR "'$$wf[$ii]' ";
		while ($$wf[$ii] eq "]") {	# array definition, find match 
			$n = 1;
			do {
				$ii--;
				# print STDERR "'$$wf[$ii]' ";
				$n++, if ($$wf[$ii] eq "]");
				$n--, if ($$wf[$ii] eq "[");
			} while ($n > 0 || $$wf[$ii] ne "[");
			$ii--;
		}
		$base_type = $$wf[$ii];
		if ($$wf[$j-1] eq "]") {
			$$i = $j;
			print STDERR "typedef arrays not supported; skipping $base_type\n";
			return "";
		}
		$typedefs{$base_type} = $is_typedef;
		$structs{$base_type}  = $is_struct;
		$unions{$base_type}   = $is_union;
	} else {
		# print STDERR "!is_typedef\n";
		$base_type = $$wf[$anchor] . " " . $$wf[$anchor + 1];
		$base_type = $$wf[$anchor + 1];
		if ($base_type ne "{") {
			$typedefs{$base_type} = $is_typedef;
			$structs{$base_type}  = $is_struct;
			$unions{$base_type}   = $is_union;
		} else {
			$is_declaration = 1;
		}
	}

	# print STDERR "sizeof($base_type)\n";
	my $ms; my $me; my $member; my @nt = ();
	my $cs; my $ce; my $ct; my $cn; my $ccs; my $cce;

	$ct = "";
	$n = 0;
	for ($ms = $first_brace + 1, $me = $first_brace+1; $me < $last_brace; ) {

		# print STDERR "$$wf[$me-1] \>$$wf[$me]\< $$wf[$me+1]\n";

		if (($$wf[$me] eq "union" || $$wf[$me] eq "struct") && $$wf[$me+1] eq "{") {
			$cn = &find_complex_member_name($wf, $me, $last_brace);
			# print STDERR "found $ct $cn\n"; 
			if (! $is_declaration) {
				if ($ct eq "struct" || length($cn) > 2) {
					if (defined($members{$base_type})) {
						$members{$base_type} .= " $cn";
					} else {
						$members{$base_type} = $cn;
					}
				}
			}
			$ms = $me + 2; $me = $ms;
			push @nt, $cn;
			# print STDERR "pushed $cn, \@nt = @nt\n"; 
			next;
		}
		if ($$wf[$me] eq "}") {
			$me++;
			$cn = pop @nt;
			# print STDERR "poped $cn, \@nt = @nt\n"; 
			$me++, while ($me < $last_brace && $$wf[$me] ne ";");
			$ms = $me + 1; $me = $ms;
			next;
		}

		$me++, while ($me < $last_brace && $$wf[$me] ne ";");
		last, if ($me >= $last_brace);

		$me--;	# remove semicolon
		last, if ($ms >= $me);	# protection for empty types

		if (! $is_declaration) {
			$member = &decode_member($wf, $ms, $me);
			# print STDERR "offsetof($base_type, $member)\n";
			$member = join('.', @nt, $member);
			if (defined($members{$base_type})) {
				$members{$base_type} .= " $member";
			} else {
				$members{$base_type} = $member;
			}
		}
		$ms = $me + 2; $me = $ms;
	}

	$$i = $j;

	return "";
}

sub tmpfile {
	my $tmp_dir  = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};
	my $tmp_name = sprintf("%s/%s-%d-%d", $tmp_dir, basename($0), $$, time());
	return $tmp_name;
}

sub target_endianess {
	my $thirty_two_bits_type = shift(@_);
	my $extra_code = shift(@_);
	if (!defined($extra_code)) { $extra_code = ""; }
	my $tmp_dir  = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};
	my $tmp_name = sprintf("%s/%s-%d-%d", $tmp_dir, basename($0), $$, time());
	my $tmp_c    = "$tmp_name.c";
	my $tmp_o    = "$tmp_name.o";
	my $tmp_bin  = "$tmp_name.bin";
	my $t_size;
	my $sb;
	my $fsize;
	my $i;

	unlink $tmp_c;

	local $SIG{'INT'} =
		sub {
			unlink $tmp_c;
			unlink $tmp_o;
			unlink $tmp_bin;
			die $_[0];
		};
	
	open(TMPFILE, ">$tmp_c") || die "Could not create temp file";
	print TMPFILE "$extra_code\n";
	print TMPFILE "const $thirty_two_bits_type tmp_val = 0x01234567LU;\n"; 
	close(TMPFILE);

	`$CC $CFLAGS -c $tmp_c -o $tmp_o`;		die, if $? != 0;
	`$OBJCOPY $OBJFLAGS $tmp_o $tmp_bin`;	die, if $? != 0;

	$sb = stat($tmp_bin);
	$fsize = $sb->size;

	my $read_bytes;
	my $buf;
	open(TMPFILE, "<$tmp_bin") || die "Could not open binary file";
	($read_bytes = read TMPFILE, $buf, 4) == 4 || die "File has illegal size";
	my @v;
	($v[0], $v[1], $v[2], $v[3]) = unpack("C4", $buf);
	close(TMPFILE);

	unlink $tmp_c;
	unlink $tmp_o;
	unlink $tmp_bin;

	local $SIG{'INT'} = 'DEFAULT';

	if ($v[0] == 0x01 && $v[1] == 0x23 && $v[2] == 0x45 && $v[3] == 0x67) {
		return("big");
	}
	if ($v[3] == 0x01 && $v[2] == 0x23 && $v[1] == 0x45 && $v[0] == 0x67) {
		return("little");
	}
	return("unknown");
}

sub alligned_type_size {
	my $type = shift(@_);
	my $type_val = shift(@_);
	if (!defined($type_val)) { $type_val = "0"; }
	my $array_size = shift(@_);
	if (!defined($array_size)) { $array_size = 16; }
	my $extra_code = shift(@_);
	if (!defined($extra_code)) { $extra_code = ""; }

	my $tmp_dir  = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};
	my $tmp_name = sprintf("%s/%s-%d-%d", $tmp_dir, basename($0), $$, time());
	my $tmp_c    = "$tmp_name.c";
	my $tmp_o    = "$tmp_name.o";
	my $tmp_bin  = "$tmp_name.bin";
	my $t_size;
	my $sb;
	my $fsize;
	my $i;

	# first find out the size of the size_t type

	unlink $tmp_c;

	local $SIG{'INT'} =
		sub {
			unlink $tmp_c;
			unlink $tmp_o;
			unlink $tmp_bin;
			die $_[0];
		};

	open(TMPFILE, ">$tmp_c") || die "Could not create temp file";
	print TMPFILE "$extra_code\n";
	print TMPFILE "const $type tmp_array[$array_size] = {\n";
	for ($i = 0; $i < $array_size; $i++) {
		print TMPFILE "$type_val,\n";
	}
	print TMPFILE "};\n";
	close(TMPFILE);

	`$CC $CFLAGS -c $tmp_c -o $tmp_o`;		die, if $? != 0;
	`$OBJCOPY $OBJFLAGS $tmp_o $tmp_bin`;	die, if $? != 0;

	$sb = stat($tmp_bin);
	$fsize = $sb->size;

	$t_size = $fsize / $array_size;

	unlink $tmp_c;
	unlink $tmp_o;
	unlink $tmp_bin;

	local $SIG{'INT'} = 'DEFAULT';

	return $t_size;
}

sub members_offset {
	my $endianess	= shift(@_);	# big or little
	my $thirty_two_bits_type = shift(@_);
	my $extra_code  = shift(@_);	# 
	my $base   		= shift(@_);	# base type
	my $members		= shift(@_);	# member to find the offset
	my $offset = 0;
	my @offsets = ();
	my $i;
	my $j;

	my $tmp_dir  = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};
	my $tmp_name = sprintf("%s/%s-%d-%d", $tmp_dir, basename($0), $$, time());
	my $tmp_c    = "$tmp_name.c";
	my $tmp_o    = "$tmp_name.o";
	my $tmp_bin  = "$tmp_name.bin";

	unlink $tmp_c;

	local $SIG{'INT'} =
		sub {
			unlink $tmp_c;
			unlink $tmp_o;
			unlink $tmp_bin;
			die $_[0];
		};

	open(TMPFILE, ">$tmp_c") || die "Could not create temp file";
	print TMPFILE "$extra_code\n";
	print TMPFILE "#include <stddef.h>\n";

	$j = $#$members + 1;
	print TMPFILE "const $thirty_two_bits_type offset_table[$j] = {\n";
	foreach (@$members) {
		print TMPFILE "\toffsetof($base, $_),\n";
	}
	print TMPFILE "};\n";

	close(TMPFILE);

	`$CC $CFLAGS -c $tmp_c -o $tmp_o`;		die, if $? != 0;
	`$OBJCOPY $OBJFLAGS $tmp_o $tmp_bin`;	die, if $? != 0;

	my $read_bytes;
	my $buf;
	open(TMPFILE, "<$tmp_bin") || die "Could not open binary file";
	
	for ($i = 0; $i < $j; $i++) {
		($read_bytes = read TMPFILE, $buf, 4) == 4 || die "File has illegal size";
		if ($endianess eq "big") {
			($offset) = unpack("N", $buf);	# big endian 32 bits
		} else {
			($offset) = unpack("V", $buf);	# little endian 32 bits
		}
		push @offsets, $offset;
	}

	close(TMPFILE);

	unlink $tmp_c;
	unlink $tmp_o;
	unlink $tmp_bin;

	local $SIG{'INT'} = 'DEFAULT';

	return(@offsets);
}


sub base_type_size {
	my $endianess	= shift(@_);	# big or little
	my $thirty_two_bits_type = shift(@_);
	my $extra_code  = shift(@_);	# 
	my $base   		= shift(@_);	# base type
	my $size = 0;

	my $tmp_dir  = -d '/tmp' ? '/tmp' : $ENV{TMP} || $ENV{TEMP};
	my $tmp_name = sprintf("%s/%s-%d-%d", $tmp_dir, basename($0), $$, time());
	my $tmp_c    = "$tmp_name.c";
	my $tmp_o    = "$tmp_name.o";
	my $tmp_bin  = "$tmp_name.bin";

	unlink $tmp_c;

	local $SIG{'INT'} =
		sub {
			unlink $tmp_c;
			unlink $tmp_o;
			unlink $tmp_bin;
			die $_[0];
		};

	open(TMPFILE, ">$tmp_c") || die "Could not create temp file";
	print TMPFILE "$extra_code\n";
	print TMPFILE "#include <stddef.h>\n";
	print TMPFILE "const $thirty_two_bits_type size = sizeof($base);\n";
	close(TMPFILE);

	`$CC $CFLAGS -c $tmp_c -o $tmp_o`;		die, if $? != 0;
	`$OBJCOPY $OBJFLAGS $tmp_o $tmp_bin`;	die, if $? != 0;

	my $read_bytes;
	my $buf;
	open(TMPFILE, "<$tmp_bin") || die "Could not open binary file";
	($read_bytes = read TMPFILE, $buf, 4) == 4 || die "File has illegal size";
	if ($endianess eq "big") {
		($size) = unpack("N", $buf);	# big endian 32 bits
	} else {
		($size) = unpack("V", $buf);	# little endian 32 bits
	}

	close(TMPFILE);

	unlink $tmp_c;
	unlink $tmp_o;
	unlink $tmp_bin;

	local $SIG{'INT'} = 'DEFAULT';

	return($size);
}

sub find_32bit_type {
	my $sizeof_int   = &alligned_type_size("int",    "0", 16, "");
	my $sizeof_short = &alligned_type_size("short",  "0", 16, "");
 	my $sizeof_long  = &alligned_type_size("long",   "0", 16, "");
	my $u32;

	if ($sizeof_int  == 4) {
		$u32 = "unsigned int"; $s32 = "signed int"; 
	} elsif ($sizeof_long == 4) {
		$u32 = "unsigned long"; $s32 = "signed long"; 
	} elsif ($sizeof_short == 4) {
		$u32 = "unsigned short"; $s32 = "signed short"; 
	} else {
		die "Not one 32 bit type found!\n";
	}
	return $u32;
}

[-- Attachment #3: tst.h --]
[-- Type: text/plain, Size: 201 bytes --]

#ifndef TST_H
#define TST_H

#include "tst2.h"

#define TST_DEF	0x10

struct tst {
	int tst_member_a;
	union {
		char *tst_u_str;
	} tst_member_b;
#ifdef SHOW_HIDDEN
	int tst_hidden;
#endif
};

#endif

[-- Attachment #4: tst2.h --]
[-- Type: text/plain, Size: 38 bytes --]

#ifndef TST2_H
#define TST2_H

#endif

[-- Attachment #5: tst.inc --]
[-- Type: text/plain, Size: 629 bytes --]

#ifndef _TST_INC
#define _TST_INC

#include "tst2.inc"

/****************************************************************

	Offsets for tst

****************************************************************/

#define tst_member_a                     0
#define tst_member_b                     4
#define tst_member_b_tst_u_str           4
#define struct_tst_SIZE                  8

/****************************************************************

	Simple defines list 

****************************************************************/

#define TST_H                         
#define TST_DEF                        0x10

#endif

[-- Attachment #6: tst-hidden.inc --]
[-- Type: text/plain, Size: 672 bytes --]

#ifndef _TST_INC
#define _TST_INC

#include "tst2.inc"

/****************************************************************

	Offsets for tst

****************************************************************/

#define tst_member_a                     0
#define tst_member_b                     4
#define tst_member_b_tst_u_str           4
#define tst_hidden                       8
#define struct_tst_SIZE                 12

/****************************************************************

	Simple defines list 

****************************************************************/

#define TST_H                         
#define TST_DEF                        0x10

#endif

[-- Attachment #7: tst2.inc --]
[-- Type: text/plain, Size: 241 bytes --]

#ifndef _TST2_INC
#define _TST2_INC

/****************************************************************

	Simple defines list 

****************************************************************/

#define TST2_H                        

#endif

  reply	other threads:[~2001-10-09  7:36 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-10-04 11:47 [RFC] Standard way of generating assembler offsets Keith Owens
2001-10-04 15:36 ` george anzinger
2001-10-05  5:48   ` Keith Owens
2001-10-06  5:21 ` Keith Owens
2001-10-08  9:35 ` Pantelis Antoniou
2001-10-08 17:29   ` george anzinger
2001-10-08 17:56   ` Georg Nikodym
2001-10-08 19:00     ` george anzinger
2001-10-09  7:38       ` Pantelis Antoniou [this message]
2001-10-09  9:28       ` David S. Miller
2001-10-08  9:49 ` David S. Miller
2001-10-09  7:25   ` Pantelis Antoniou
2001-10-09  9:24   ` David S. Miller
2001-10-14 11:27   ` Keith Owens

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3BC2A98C.A57EA360@intracom.gr \
    --to=panto@intracom.gr \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).