1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
use Config;
$file = @ARGV ? shift : 'examples/memmap.pl';
open OUT, ">$file" or die "Can't create $file: $!";
print OUT <<"!GROK!THIS!";
$Config{startperl} -w
!GROK!THIS!
print OUT <<'!NO!SUBS!';
################################################################################
#
# Copyright (c) 2002-2024 Marcus Holland-Moritz. All rights reserved.
# This program is free software; you can redistribute it and/or modify
# it under the same terms as Perl itself.
#
################################################################################
#===============================================================================
#
# Print a simple memory map of a structure.
#
#===============================================================================
use Convert::Binary::C;
use Data::Dumper;
use strict;
#-----------------------------------------------------
# Create an object, configure it, and parse some code.
#-----------------------------------------------------
my $c = Convert::Binary::C->new( PointerSize => 4,
LongSize => 4,
ShortSize => 2,
Alignment => 4 )
->parse( <<'ENDC' );
typedef unsigned long u_32;
typedef struct _LinkedList * LinkedList;
typedef struct _HashTable * HashTable;
typedef struct {
enum {
BO_BIG_ENDIAN,
BO_LITTLE_ENDIAN
} bo;
} ArchSpecs;
typedef struct {
char *buffer;
long pos, length;
} Buffer;
typedef struct {
unsigned alignment;
unsigned int_size;
unsigned short_size;
unsigned long_size;
unsigned long_long_size;
int enum_size;
unsigned ptr_size;
unsigned float_size;
unsigned double_size;
unsigned long_double_size;
u_32 flags;
u_32 keywords;
LinkedList disabled_keywords;
LinkedList includes;
LinkedList defines;
LinkedList assertions;
HashTable keyword_map;
} CParseConfig;
typedef struct {
LinkedList enums;
LinkedList structs;
LinkedList typedef_lists;
HashTable htEnumerators;
HashTable htEnums;
HashTable htStructs;
HashTable htTypedefs;
HashTable htFiles;
char *errstr;
} CParseInfo;
typedef struct {
char *bufptr;
unsigned alignment;
unsigned align_base;
int dataTooShortFlag;
Buffer buf;
CParseConfig cfg;
CParseInfo cpi;
ArchSpecs as;
enum {
ET_INTEGER, ET_STRING, ET_BOTH
} enumType;
} CBC;
ENDC
#-------------------------------------------------
# Print the memory map for type 'CBC' with a base
# address of 0x01500000.
#-------------------------------------------------
memmap( $c, 'CBC', 0x01500000 );
#==========================================================
# SUBROUTINES
#==========================================================
sub memmap
{
my($c, $type, $start) = @_;
$start ||= 0;
my $afmt = '%0' . 2*$c->PointerSize . 'X';
for my $offset ( 0 .. $c->sizeof( $type ) - 1 ) {
my $m = $c->member( $type, $offset );
rindex( $m, '+' ) < 0 or next;
my $t = $c->typeof( $type.$m );
printf "$afmt %-16s %s\n", $start+$offset, $t, $m;
}
}
!NO!SUBS!
close OUT or die "Can't close $file: $!";
chmod 0755, $file or die "Can't reset permissions for $file: $!\n";
|