From ff9f9a92c7c867aeeca2e0bfb9787b747be6808d Mon Sep 17 00:00:00 2001 From: Kent Fredric Date: Fri, 14 Aug 2015 18:33:01 +1200 Subject: [PATCH] Build results of 501ae48 (on master) --- Changes | 13 + MANIFEST | 1 + META.json | 49 +-- META.yml | 15 +- Makefile.PL | 8 +- lib/ELF/Extract/Sections.pm | 353 ++++---------------- lib/ELF/Extract/Sections/Meta/Scanner.pm | 35 +- lib/ELF/Extract/Sections/Meta/Types.pm | 8 +- lib/ELF/Extract/Sections/Scanner/Objdump.pm | 316 ++---------------- lib/ELF/Extract/Sections/Section.pm | 165 +++------ maint/perlcritic.rc.gen.pl | 1 + misc/Changes.deps | 10 +- misc/Changes.deps.all | 10 +- misc/Changes.deps.dev | 4 +- misc/Changes.deps.opt | 4 +- misc/built_with.json | 5 +- perlcritic.rc | 2 +- t/00-report-prereqs.dd | 3 + t/00-version-check.t | 48 +++ weaver.ini | 23 -- xt/author/eol.t | 1 + 21 files changed, 304 insertions(+), 770 deletions(-) create mode 100644 t/00-version-check.t diff --git a/Changes b/Changes index 9be3c41..0a78a8b 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,18 @@ Revision history for ELF-Extract-Sections +1.001000 2015-08-14T06:32:18Z 4d78d05 + [Dependencies::Stats] + - Dependencies changed since 1.000000, see misc/*.deps* for details + - runtime: +1 + - test: +2 + + [Internals] + - Parameter handling delegated to MooseX::Params::Validate + - TODO: guard against spurious bless() causing problems, re rt#106192 + + [Tests] + - Probing for version data to make a better verison check + 1.000000 2015-07-30T16:49:16Z 1c37bc4 [!Major] - This release includes some respectably significant changes. diff --git a/MANIFEST b/MANIFEST index ebfe204..fbf491e 100644 --- a/MANIFEST +++ b/MANIFEST @@ -40,6 +40,7 @@ t/00-compile/lib_ELF_Extract_Sections_Section_pm.t t/00-compile/lib_ELF_Extract_Sections_pm.t t/00-report-prereqs.dd t/00-report-prereqs.t +t/00-version-check.t t/01-elf-libs.t t/test_files/gen_expected.pl t/test_files/libc.so.6 diff --git a/META.json b/META.json index 66d870c..87cf634 100644 --- a/META.json +++ b/META.json @@ -107,6 +107,7 @@ "Moose::Role" : "0", "MooseX::Has::Sugar" : "0.0300", "MooseX::Log::Log4perl" : "0.31", + "MooseX::Params::Validate" : "0", "MooseX::Types" : "0.10", "MooseX::Types::Moose" : "0.10", "MooseX::Types::Path::Tiny" : "0", @@ -124,8 +125,10 @@ "Test::More" : "0.99" }, "requires" : { + "Capture::Tiny" : "0", "ExtUtils::MakeMaker" : "0", "File::Spec" : "0", + "File::Which" : "0", "FindBin" : "0", "Log::Log4perl" : "1.21", "Path::Iterator::Rule" : "0", @@ -140,23 +143,23 @@ "provides" : { "ELF::Extract::Sections" : { "file" : "lib/ELF/Extract/Sections.pm", - "version" : "1.000000" + "version" : "1.001000" }, "ELF::Extract::Sections::Meta::Scanner" : { "file" : "lib/ELF/Extract/Sections/Meta/Scanner.pm", - "version" : "1.000000" + "version" : "1.001000" }, "ELF::Extract::Sections::Meta::Types" : { "file" : "lib/ELF/Extract/Sections/Meta/Types.pm", - "version" : "1.000000" + "version" : "1.001000" }, "ELF::Extract::Sections::Scanner::Objdump" : { "file" : "lib/ELF/Extract/Sections/Scanner/Objdump.pm", - "version" : "1.000000" + "version" : "1.001000" }, "ELF::Extract::Sections::Section" : { "file" : "lib/ELF/Extract/Sections/Section.pm", - "version" : "1.000000" + "version" : "1.001000" } }, "release_status" : "stable", @@ -171,7 +174,7 @@ "web" : "https://github.com/kentnl/ELF-Extract-Sections" } }, - "version" : "1.000000", + "version" : "1.001000", "x_BuiltWith" : { "external_file" : "misc/built_with.json" }, @@ -476,11 +479,6 @@ "name" : "DESCRIPTION", "version" : "4.012" }, - { - "class" : "Pod::Weaver::Section::Generic", - "name" : "NAMING_SCHEME", - "version" : "4.012" - }, { "class" : "Pod::Weaver::Section::Generic", "name" : "OVERVIEW", @@ -496,31 +494,6 @@ "name" : "ATTRIBUTES", "version" : "4.012" }, - { - "class" : "Pod::Weaver::Section::Collect", - "name" : "FILTER_METHODS", - "version" : "4.012" - }, - { - "class" : "Pod::Weaver::Section::Collect", - "name" : "TERMINATOR_LIST_METHODS", - "version" : "4.012" - }, - { - "class" : "Pod::Weaver::Section::Collect", - "name" : "MIRROR_LIST_METHODS", - "version" : "4.012" - }, - { - "class" : "Pod::Weaver::Section::Collect", - "name" : "PRIVATE_ATTRIBUTES", - "version" : "4.012" - }, - { - "class" : "Pod::Weaver::Section::Collect", - "name" : "PRIVATE_METHODS", - "version" : "4.012" - }, { "class" : "Pod::Weaver::Section::Leftovers", "name" : "Leftovers", @@ -683,7 +656,7 @@ "Dist::Zilla::Plugin::Git::Tag" : { "branch" : null, "signed" : 0, - "tag" : "1.000000-source", + "tag" : "1.001000-source", "tag_format" : "%v-source", "tag_message" : "v%v", "time_zone" : "local" @@ -759,7 +732,7 @@ "Dist::Zilla::Plugin::Git::Tag" : { "branch" : "releases", "signed" : 0, - "tag" : "1.000000", + "tag" : "1.001000", "tag_format" : "%v", "tag_message" : "v%v", "time_zone" : "local" diff --git a/META.yml b/META.yml index f087274..f36a43a 100644 --- a/META.yml +++ b/META.yml @@ -3,8 +3,10 @@ abstract: 'Extract Raw Chunks of data from identifiable ELF Sections' author: - 'Kent Fredric ' build_requires: + Capture::Tiny: '0' ExtUtils::MakeMaker: '0' File::Spec: '0' + File::Which: '0' FindBin: '0' Log::Log4perl: '1.21' Path::Iterator::Rule: '0' @@ -27,19 +29,19 @@ name: ELF-Extract-Sections provides: ELF::Extract::Sections: file: lib/ELF/Extract/Sections.pm - version: '1.000000' + version: '1.001000' ELF::Extract::Sections::Meta::Scanner: file: lib/ELF/Extract/Sections/Meta/Scanner.pm - version: '1.000000' + version: '1.001000' ELF::Extract::Sections::Meta::Types: file: lib/ELF/Extract/Sections/Meta/Types.pm - version: '1.000000' + version: '1.001000' ELF::Extract::Sections::Scanner::Objdump: file: lib/ELF/Extract/Sections/Scanner/Objdump.pm - version: '1.000000' + version: '1.001000' ELF::Extract::Sections::Section: file: lib/ELF/Extract/Sections/Section.pm - version: '1.000000' + version: '1.001000' recommends: Moose: '2.000' requires: @@ -50,6 +52,7 @@ requires: Moose::Role: '0' MooseX::Has::Sugar: '0.0300' MooseX::Log::Log4perl: '0.31' + MooseX::Params::Validate: '0' MooseX::Types: '0.10' MooseX::Types::Moose: '0.10' MooseX::Types::Path::Tiny: '0' @@ -61,4 +64,4 @@ resources: bugtracker: https://github.com/kentnl/ELF-Extract-Sections/issues homepage: https://github.com/kentnl/ELF-Extract-Sections repository: https://github.com/kentnl/ELF-Extract-Sections.git -version: '1.000000' +version: '1.001000' diff --git a/Makefile.PL b/Makefile.PL index c161a3f..93c462e 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -30,6 +30,7 @@ my %WriteMakefileArgs = ( "Moose::Role" => 0, "MooseX::Has::Sugar" => "0.0300", "MooseX::Log::Log4perl" => "0.31", + "MooseX::Params::Validate" => 0, "MooseX::Types" => "0.10", "MooseX::Types::Moose" => "0.10", "MooseX::Types::Path::Tiny" => 0, @@ -38,8 +39,10 @@ my %WriteMakefileArgs = ( "warnings" => 0 }, "TEST_REQUIRES" => { + "Capture::Tiny" => 0, "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, + "File::Which" => 0, "FindBin" => 0, "Log::Log4perl" => "1.21", "Path::Iterator::Rule" => 0, @@ -48,7 +51,7 @@ my %WriteMakefileArgs = ( "YAML::XS" => 0, "lib" => 0 }, - "VERSION" => "1.000000", + "VERSION" => "1.001000", "test" => { "TESTS" => "t/*.t t/00-compile/*.t" } @@ -56,10 +59,12 @@ my %WriteMakefileArgs = ( my %FallbackPrereqs = ( + "Capture::Tiny" => 0, "Carp" => 0, "Devel::CheckBin" => 0, "ExtUtils::MakeMaker" => 0, "File::Spec" => 0, + "File::Which" => 0, "FindBin" => 0, "Log::Log4perl" => "1.21", "Module::Runtime" => 0, @@ -67,6 +72,7 @@ my %FallbackPrereqs = ( "Moose::Role" => 0, "MooseX::Has::Sugar" => "0.0300", "MooseX::Log::Log4perl" => "0.31", + "MooseX::Params::Validate" => 0, "MooseX::Types" => "0.10", "MooseX::Types::Moose" => "0.10", "MooseX::Types::Path::Tiny" => 0, diff --git a/lib/ELF/Extract/Sections.pm b/lib/ELF/Extract/Sections.pm index cf89a57..646a747 100644 --- a/lib/ELF/Extract/Sections.pm +++ b/lib/ELF/Extract/Sections.pm @@ -6,7 +6,7 @@ package ELF::Extract::Sections; # ABSTRACT: Extract Raw Chunks of data from identifiable ELF Sections -our $VERSION = '1.000000'; +our $VERSION = '1.001000'; our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY @@ -14,53 +14,12 @@ use Moose qw( with has ); use Carp qw( croak ); with 'MooseX::Log::Log4perl'; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - use MooseX::Has::Sugar 0.0300; use MooseX::Types::Moose ( ':all', ); use MooseX::Types::Path::Tiny ( 'File', ); use ELF::Extract::Sections::Meta::Types ( ':all', ); use Module::Runtime ( 'require_module', ); +use MooseX::Params::Validate (qw( validated_list pos_validated_list )); require ELF::Extract::Sections::Section; @@ -70,9 +29,6 @@ require ELF::Extract::Sections::Section; - - - has 'file' => ( isa => File, ro, required, coerce, ); @@ -107,8 +63,6 @@ has 'scanner' => ( isa => Str, ro, default => 'Objdump', ); - - sub BUILD { my ( $self, ) = @_; if ( not $self->file->stat ) { @@ -147,64 +101,19 @@ sub BUILD { -sub _argument { - my ( $args, $number, $type, %flags ) = @_; - return if not $flags{required} and @{$args} < $number + 1; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - - @{$args} >= $number + 1 or croak "Argument $number of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->[$number] ) and return $args->[$number]; - } - else { - my $value = $type->coerce( $args->[$number] ); - return $value if $value; - } - return croak "Argument $number was not of type $type$can_coerce: " . $type->get_message( $args->[$number] ); - -} -sub _parameter { - my ( $args, $name, $type, %flags ) = @_; - return if not $flags{required} and not exists $args->{$name}; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - exists $args->{$name} or croak "Parameter '$name' of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->{$name} ) and return delete $args->{$name}; - } - else { - my $value = $type->coerce( delete $args->{$name} ); - return $value if $value; - } - return croak "Parameter '$name' was not of type $type$can_coerce: " . $type->get_message( $args->{$name} ); -} sub sorted_sections { - my ( $self, %args ) = @_; - my $field = _parameter( \%args, 'field', FilterField, required => 0 ); - my $descending = _parameter( \%args, 'descending', Bool, required => 0 ); - if ( keys %args ) { - croak "Unknown parameters @{[ keys %args ]}"; - } + my ( $self, $field, $descending ) = validated_list( + \@_, + 'field' => { isa => FilterField, optional => 1 }, + 'descending' => { isa => Bool, optional => 1 }, + ); my $m = 1; $m = 0 - 1 if ($descending); return [ sort { $m * ( $a->compare( other => $b, field => $field ) ) } values %{ $self->sections } ]; } - - - - - - - - - - - - sub _build_sections { my ($self) = @_; $self->log->debug('Building Section List'); @@ -216,51 +125,27 @@ sub _build_sections { } } - - - - - - - - - - has '_scanner_package' => ( isa => ClassName, ro, lazy_build, ); - - - - - - has '_scanner_instance' => ( isa => Object, ro, lazy_build, ); __PACKAGE__->meta->make_immutable; no Moose; - - - - sub _error_scanner_missing { my ( $self, @args ) = @_; - @args < 4 or croak 'Too many arguments'; - my $scanner = _argument( \@args, 0, Str, required => 1 ); - my $package = _argument( \@args, 1, Str, required => 1 ); - my $error = _argument( \@args, 2, Str, required => 1 ); + my ( $scanner, $package, $error ) = pos_validated_list( + \@args, + { isa => Str, }, # + { isa => Str, }, # + { isa => Str, }, # + ); my $message = sprintf qq[The Scanner %s could not be found as %s\n.], $scanner, $package; $message .= '>' . $error; $self->log->logconfess($message); return; } - - - - - - sub _build__scanner_package { my ($self) = @_; my $pkg = 'ELF::Extract::Sections::Scanner::' . $self->scanner; @@ -271,35 +156,20 @@ sub _build__scanner_package { return $pkg; } - - - - - - sub _build__scanner_instance { my ($self) = @_; my $instance = $self->_scanner_package->new(); return $instance; } - - - - - - - - - - sub _warn_stash_collision { my ( $self, @args ) = @_; - @args < 4 or croak 'Too many arguments'; - my $stashname = _argument( \@args, 0, Str, required => 1 ); - my $header = _argument( \@args, 1, Str, required => 1 ); - my $offset = _argument( \@args, 2, Str, required => 1 ); - + my ( $stashname, $header, $offset ) = pos_validated_list( + \@args, + { isa => Str, }, # + { isa => Str, }, + { isa => Str, }, + ); my $message = q[Warning, duplicate file offset reported by scanner.]; $message .= sprintf q[<%s> and <%s> collide at <%s>.], $stashname, $header, $offset; $message .= sprintf q[Assuming <%s> is empty and replacing it.], $stashname; @@ -307,21 +177,14 @@ sub _warn_stash_collision { return; } - - - - - - - - sub _stash_record { my ( $self, @args ) = @_; - @args < 4 or croak 'Too many arguments'; - my $stash = _argument( \@args, 0, HashRef, required => 1 ); - my $header = _argument( \@args, 1, Str, required => 1 ); - my $offset = _argument( \@args, 2, Str, required => 1 ); - + my ( $stash, $header, $offset ) = pos_validated_list( + \@args, + { isa => HashRef, }, # + { isa => Str, }, + { isa => Str, }, + ); if ( exists $stash->{$offset} ) { $self->_warn_stash_collision( $stash->{$offset}, $header, $offset ); } @@ -329,23 +192,15 @@ sub _stash_record { return; } - - - - - - - - - sub _build_section_section { my ( $self, @args ) = @_; - @args < 5 or croak 'Too many arguments'; - my $stashName = _argument( \@args, 0, Str, required => 1 ); - my $start = _argument( \@args, 1, Int, required => 1 ); - my $stop = _argument( \@args, 2, Int, required => 1 ); - my $file = _argument( \@args, 3, File, required => 1 ); - + my ( $stashName, $start, $stop, $file ) = pos_validated_list( + \@args, + { isa => Str, required => 1 }, + { isa => Int, required => 1 }, + { isa => Int, required => 1 }, + { isa => File, required => 1 }, + ); $self->log->info(" Section ${stashName} , ${start} -> ${stop} "); return ELF::Extract::Sections::Section->new( offset => $start, @@ -355,17 +210,12 @@ sub _build_section_section { ); } - - - - - - - sub _build_section_table { my ( $self, @args ) = @_; - @args < 2 or croak 'Too many arguments'; - my $ob = _argument( \@args, 0, HashRef, required => 1 ); + my ($ob) = pos_validated_list( + \@args, # + { isa => HashRef }, + ); my %datastash = (); my @k = sort { $a <=> $b } keys %{$ob}; my $i = 0; @@ -376,14 +226,6 @@ sub _build_section_table { return \%datastash; } - - - - - - - - sub _scan_guess_size { my ($self) = @_; @@ -398,13 +240,6 @@ sub _scan_guess_size { return $self->_build_section_table( \%offsets ); } - - - - - - - sub _scan_with_size { my ($self) = @_; my %datastash = (); @@ -432,7 +267,7 @@ ELF::Extract::Sections - Extract Raw Chunks of data from identifiable ELF Sectio =head1 VERSION -version 1.000000 +version 1.001000 =head1 SYNOPSIS @@ -453,58 +288,25 @@ version 1.000000 # Get the raw bytes out of the section. print $data->contents # returns bytes -=head1 CAVEATS - -=over 4 - -=item 1. Beta Software - -This code is relatively new. It exists only as a best attempt at present until further notice. It -has proved as practical for at least one application, and this is why the module exists. However, it can't be -guaranteed it will work for whatever you want it to in all cases. Please report any bugs you find. - -=item 2. Feature Incomplete - -This only presently has a very bare-bones functionality, which should however prove practical for most purposes. -If you have any suggestions, please tell me via "report bugs". If you never seek, you'll never find. +=head1 METHODS -=item 3. Humans - -This code is written by a human, and like all human code, it sucks. There will be bugs. Please report them. +=head2 C -=back - -=head1 PUBLIC ATTRIBUTES - -=head2 file - -Returns the file the section data is being created for. - -=head2 sections - -Returns a HashRef of the available sections. - -=head2 scanner - -Returns the name of the default scanner plug-in - -=head1 PUBLIC METHODS - -=head2 new ( file => FILENAME ) + my $object = ELF::Extract::Sections->new( file => FILENAME ); Creates A new Section Extractor object with the default scanner -=head2 new ( file => FILENAME , scanner => 'Objdump' ) + my $object = ELF::Extract::Sections->new( file => FILENAME , scanner => 'Objdump' ) Creates A new Section Extractor object with the specified scanner -=for Pod::Coverage BUILD +=head2 C -=head2 sorted_sections ( field => SORT_BY ) + my $sections = $object->sorted_sections( field => SORT_BY ) Returns an ArrayRef sorted by the SORT_BY field, in the default order. -=head2 sorted_sections ( field => SORT_BY, descending => DESCENDING ) + my $sections = $object->sorted_sections( field => SORT_BY, descending => DESCENDING ); Returns an ArrayRef sorted by the SORT_BY field. May be Ascending or Descending depending on requirements. @@ -528,69 +330,42 @@ The Sections offset relative to the start of the file. The Size of the section. -=head1 PUBLIC ATTRIBUTE BUILDERS - -These aren't really user serviceable, but they make your front end work. - -=head2 _build_sections - -See L - -=head1 PRIVATE ATTRIBUTES - -=head2 _scanner_package - - isa => ClassName, ro, lazy_build - -=head2 _scanner_instance - - isa => Object, ro, lazy_build +=head1 ATTRIBUTES -=head1 PRIVATE ATTRIBUTE BUILDERS +=head2 C -=head2 _build__scanner_package - -Builds L - -=head2 _build__scanner_instance - -Builds L - -=head1 PRIVATE_METHODS - -=head2 _warn_stash_collision - - method _warn_stash_collision ( Str $stashname!, Str $header!, Str $offset! ) { +Returns the file the section data is being created for. - } +=head2 C -=head2 _stash_record( HashRef, Str, Str ) +Returns a HashRef of the available sections. - method _stash_record ( HashRef $stash! , Str $header!, Str $offset! ) { +=head2 C - } +Returns the name of the default scanner plug-in -=head2 _build_section_section( Str, Int, Int, File ) +=for Pod::Coverage BUILD - method _build_section_section ( Str $stashName, Int $start, Int $stop , File $file ) { +=head1 CAVEATS - } +=over 4 -=head2 _build_section_table( HashRef ) +=item 1. Beta Software - method _build_section_table ( HashRef $ob! ) { - } +This code is relatively new. It exists only as a best attempt at present until further notice. It +has proved as practical for at least one application, and this is why the module exists. However, it can't be +guaranteed it will work for whatever you want it to in all cases. Please report any bugs you find. -=head2 _scan_guess_size +=item 2. Feature Incomplete - method _scan_guess_size { +This only presently has a very bare-bones functionality, which should however prove practical for most purposes. +If you have any suggestions, please tell me via "report bugs". If you never seek, you'll never find. - } +=item 3. Humans -=head2 _scan_with_size +This code is written by a human, and like all human code, it sucks. There will be bugs. Please report them. - method _scan_with_size { - } +=back =head1 DEBUGGING diff --git a/lib/ELF/Extract/Sections/Meta/Scanner.pm b/lib/ELF/Extract/Sections/Meta/Scanner.pm index 7182d38..34178c2 100644 --- a/lib/ELF/Extract/Sections/Meta/Scanner.pm +++ b/lib/ELF/Extract/Sections/Meta/Scanner.pm @@ -6,14 +6,19 @@ package ELF::Extract::Sections::Meta::Scanner; # ABSTRACT: Interface Contract for Scanners -our $VERSION = '1.000000'; +our $VERSION = '1.001000'; our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY use Moose::Role qw( with requires ); with 'MooseX::Log::Log4perl'; -requires( 'open_file', 'next_section', 'section_offset', 'section_size', 'section_name', 'can_compute_size' ); +requires 'open_file'; +requires 'next_section'; +requires 'section_offset'; +requires 'section_size'; +requires 'section_name'; +requires 'can_compute_size'; no Moose::Role; @@ -31,34 +36,46 @@ ELF::Extract::Sections::Meta::Scanner - Interface Contract for Scanners =head1 VERSION -version 1.000000 +version 1.001000 =head1 Required Methods for Applying Roles -=head2 -> open_file file => FILE +=head2 C + + my $file = $scanner->open_file( file => FILE ) Must take a file name and assume a state reset. -=head2 -> next_section +=head2 C + + my $boolean = $scanner->next_section Must return true if a section was discovered. Must return false otherwise. This method is called before getting data out. -=head2 -> section_offset +=head2 C + + my $offset = $scanner->section_offset; Returns the offset as an Integer -=head2 -> section_size +=head2 C + + my $size = $scanner->section_size; Returns the sections computed size ( if possible ) If you can't compute the size, please call $self->log->logcroak() -=head2 -> section_name +=head2 C + + my $name = $scanner->section_name; Returns the sections name -=head2 -> can_compute_size +=head2 C + + my $boolean = $scanner->can_compute_size; This returns whether or not this code is capable of discerning section sizes on its own. return 1 if true, return C otherwise. diff --git a/lib/ELF/Extract/Sections/Meta/Types.pm b/lib/ELF/Extract/Sections/Meta/Types.pm index 397c079..0aeba8c 100644 --- a/lib/ELF/Extract/Sections/Meta/Types.pm +++ b/lib/ELF/Extract/Sections/Meta/Types.pm @@ -6,7 +6,7 @@ package ELF::Extract::Sections::Meta::Types; # ABSTRACT: Generic Type Constraints for E:E:S -our $VERSION = '1.000000'; +our $VERSION = '1.001000'; our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY @@ -32,15 +32,15 @@ ELF::Extract::Sections::Meta::Types - Generic Type Constraints for E:E:S =head1 VERSION -version 1.000000 +version 1.001000 =head1 Types -=head2 FilterField +=head2 C ENUM: name, offset, size -=head2 ElfSection +=head2 C An object that is a ELF::Extract::Sections::Section diff --git a/lib/ELF/Extract/Sections/Scanner/Objdump.pm b/lib/ELF/Extract/Sections/Scanner/Objdump.pm index d3cc40c..4b6ebe0 100644 --- a/lib/ELF/Extract/Sections/Scanner/Objdump.pm +++ b/lib/ELF/Extract/Sections/Scanner/Objdump.pm @@ -6,69 +6,19 @@ package ELF::Extract::Sections::Scanner::Objdump; # ABSTRACT: An objdump based section scanner. -our $VERSION = '1.000000'; +our $VERSION = '1.001000'; our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY use Moose qw( with has ); with 'ELF::Extract::Sections::Meta::Scanner'; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - use Carp qw( croak ); use MooseX::Has::Sugar 0.0300; - - - - - - - - -use MooseX::Types::Moose (qw( Bool HashRef RegexpRef FileHandle Undef Str Int)); - - - - - - - - - +use MooseX::Types::Moose (qw( Bool HashRef RegexpRef FileHandle Undef Str Int)); use MooseX::Types::Path::Tiny ('File'); +use MooseX::Params::Validate (qw( validated_list )); @@ -80,48 +30,8 @@ use MooseX::Types::Path::Tiny ('File'); - - -sub _argument { - my ( $args, $number, $type, %flags ) = @_; - return if not $flags{required} and @{$args} < $number + 1; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - - @{$args} >= $number + 1 or croak "Argument $number of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->[$number] ) and return $args->[$number]; - } - else { - my $value = $type->coerce( $args->[$number] ); - return $value if $value; - } - return croak "Argument $number was not of type $type$can_coerce: " . $type->get_message( $args->[$number] ); - -} - -sub _parameter { - my ( $args, $name, $type, %flags ) = @_; - return if not $flags{required} and not exists $args->{$name}; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - exists $args->{$name} or croak "Parameter '$name' of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->{$name} ) and return delete $args->{$name}; - } - else { - my $value = $type->coerce( delete $args->{$name} ); - return $value if $value; - } - return croak "Parameter '$name' was not of type $type$can_coerce: " . $type->get_message( $args->{$name} ); -} - sub open_file { - my ( $self, %args ) = @_; - my $file = _parameter( \%args, 'file', File, required => 1 ); - if ( keys %args ) { - croak "Unknown parameters @{[ keys %args ]}"; - } + my ( $self, $file ) = validated_list( \@_, file => { isa => File, }, ); $self->log->debug("Opening $file"); $self->_file($file); $self->_filehandle( $self->_objdump ); @@ -136,6 +46,8 @@ sub open_file { + + sub next_section { my ($self) = @_; my $re = $self->_section_header_identifier; @@ -161,6 +73,8 @@ sub next_section { + + sub section_offset { my ($self) = @_; if ( not $self->_has_state ) { @@ -178,6 +92,8 @@ sub section_offset { + + sub section_size { my ($self) = @_; $self->log->logcroak('Can\'t perform section_size on this type of object.'); @@ -192,6 +108,8 @@ sub section_size { + + sub section_name { my ($self) = @_; if ( not $self->_has_state ) { @@ -209,24 +127,12 @@ sub section_name { + + sub can_compute_size { return 0; } - - - - - - - - - - - - - - has _header_regex => ( isa => RegexpRef, ro, @@ -235,16 +141,6 @@ has _header_regex => ( }, ); - - - - - - - - - - has _offset_regex => ( isa => RegexpRef, ro, @@ -254,54 +150,12 @@ has _offset_regex => ( }, ); - - - - - - - - has _section_header_identifier => ( isa => RegexpRef, ro, lazy_build, ); - - - - - - - - - - has _file => ( isa => File, rw, clearer => '_clear_file', ); - - - - - - - - - - has _filehandle => ( isa => FileHandle, rw, clearer => '_clear_filehandle', ); - - - - - - - - - - - - - - has _state => ( isa => HashRef, rw, @@ -311,18 +165,6 @@ has _state => ( __PACKAGE__->meta->make_immutable; no Moose; - - - - - - - - - - - - sub _build__section_header_identifier { my ($self) = @_; my $header = $self->_header_regex; @@ -331,16 +173,6 @@ sub _build__section_header_identifier { return qr/${header}\s*${offset}:/; } - - - - - - - - - - sub _objdump { my ($self) = @_; if ( open my $fh, q{-|}, q{objdump}, qw( -D -F ), $self->_file->realpath->absolute ) { @@ -364,7 +196,7 @@ ELF::Extract::Sections::Scanner::Objdump - An objdump based section scanner. =head1 VERSION -version 1.000000 +version 1.001000 =head1 SYNOPSIS @@ -380,137 +212,61 @@ TO use this module, simply initialise L as so scanner => "Objdump", ); -=head1 IMPLEMENTS ROLES - -=head2 ELF::Extract::Sections::Meta::Scanner - -L - -=head1 DEPENDS - -=head2 MooseX::Has::Sugar - -Lots of keywords. - -L - -=head2 MooseX::Types::Moose - -Type Constraining Keywords. - -L - -=head2 MooseX::Types::Path::Tiny - -File Type Constraints w/ Path::Tiny +=head1 METHODS -L +=head2 C -=head1 PUBLIC METHODS - -=head2 -> open_file ( file => File ) : Bool I< ::Scanner > + my $boolean = $scanner->open_file( file => File ); Opens the file and assigns our state to that file. L -=head2 -> next_section () : Bool I< ::Scanner > +=head2 C + + my $boolean = $scanner->next_section(); Advances our state to the next section. L -=head2 -> section_offset () : Int | Undef I< ::Scanner > +=head2 C + + my $return = $scanner->section_offset(); # Int | Undef Reports the offset of the currently open section L -=head2 -> section_size () : Undef I< ::Scanner > +=head2 C + + my $return = $scanner->section_size(); # BANG Dies, because this module can't compute section sizes. L -=head2 -> section_name () : Str | Undef I< ::Scanner > +=head2 C + + my $name = $scanner->section_name(); # Str | Undef Returns the name of the current section L -=head2 -> can_compute_size () : Bool I< ::Scanner > +=head2 C + + my $bool = $scanner->can_compute_size; Returns false L -=head1 PRIVATE ATTRIBUTES - -=head2 _header_regex : RegexpRef - -A regular expression for identifying the - - - -Style tokens that denote objdump header names. - -Note: This is not XML. - -=head2 _offset_regex : RegexpRef - -A regular expression for identifying offset blocks in objdump's output. - -They look like this: - - File Offset: 0xdeadbeef - -=head2 _section_header_identifier : RegexpRef - -A regular expression for extracting Headers and Offsets together - - File Offset: 0xdeadbeef - -=head2 _file : File - -A L reference to a file somewhere on a system - -=head3 _clear_file : _file.clearer - -Clears L - -=head2 _filehandle : FileHandle - -A perl FileHandle that points to the output of objdump for L - -=head3 _clear_file_handle : _filehandle.clearer - -Clears L - -=head2 _state : HashRef - -Keeps track of what we're doing, and what the next header is to return. - -=head3 _has_state : _state.predicate - -Returns is-set of L - -=head3 _clear_state : _state.clearer - -Clears L<_state> - -=head1 PRIVATE ATTRIBUTE BUILDERS - -=head2 -> _build__section_header_identifier : RegexpRef - -Assembles L and L - -L - -=head1 PRIVATE METHODS +=head1 IMPLEMENTS ROLES -=head2 -> _objdump : FileHandle | Undef +=head2 ELF::Extract::Sections::Meta::Scanner -Calls the system C instance for the currently processing file. +L =head1 AUTHOR diff --git a/lib/ELF/Extract/Sections/Section.pm b/lib/ELF/Extract/Sections/Section.pm index 9fbd256..dd927fc 100644 --- a/lib/ELF/Extract/Sections/Section.pm +++ b/lib/ELF/Extract/Sections/Section.pm @@ -6,95 +6,21 @@ package ELF::Extract::Sections::Section; # ABSTRACT: An Objective reference to a section in an ELF file. -our $VERSION = '1.000000'; +our $VERSION = '1.001000'; our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY use Moose; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - use Carp qw( croak ); use MooseX::Has::Sugar 0.0300; use MooseX::Types::Moose ( ':all', ); use ELF::Extract::Sections::Meta::Types ( ':all', ); use MooseX::Types::Path::Tiny ( 'File', ); +use MooseX::Params::Validate (qw( validated_list )); use overload '""' => \&to_string; -sub _argument { - my ( $args, $number, $type, %flags ) = @_; - return if not $flags{required} and @{$args} < $number + 1; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - - @{$args} >= $number + 1 or croak "Argument $number of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->[$number] ) and return $args->[$number]; - } - else { - my $value = $type->coerce( $args->[$number] ); - return $value if $value; - } - return croak "Argument $number was not of type $type$can_coerce: " . $type->get_message( $args->[$number] ); - -} - -sub _parameter { - my ( $args, $name, $type, %flags ) = @_; - return if not $flags{required} and not exists $args->{$name}; - my $can_coerce = $flags{coerce} ? '(coerceable)' : q[]; - exists $args->{$name} or croak "Parameter '$name' of type $type$can_coerce was not specified"; - - if ( not $flags{coerce} ) { - $type->check( $args->{$name} ) and return delete $args->{$name}; - } - else { - my $value = $type->coerce( delete $args->{$name} ); - return $value if $value; - } - return croak "Parameter '$name' was not of type $type$can_coerce: " . $type->get_message( $args->{$name} ); -} - - - - - @@ -147,8 +73,6 @@ no Moose; - - sub to_string { my ( $self, ) = @_; @@ -179,14 +103,14 @@ sub to_string { -sub compare { - my ( $self, %args ) = @_; - my $other = _parameter( \%args, 'other', class_type('ELF::Extract::Sections::Section'), required => 1 ); - my $field = _parameter( \%args, 'field', FilterField, required => 1 ); - if ( keys %args ) { - croak "Unknown parameters @{[ keys %args ]}"; - } + +sub compare { + my ( $self, $other, $field ) = validated_list( + \@_, + other => { isa => class_type('ELF::Extract::Sections::Section') }, + field => { isa => FilterField, }, + ); if ( 'name' eq $field ) { return ( $self->name cmp $other->name ); } @@ -213,12 +137,13 @@ sub compare { + + sub write_to { - my ( $self, %args ) = @_; - my $file = _parameter( \%args, 'file', File, required => 1, coerce => 1 ); - if ( keys %args ) { - croak "Unknown parameters @{[ keys %args ]}"; - } + my ( $self, $file ) = validated_list( + \@_, # + file => { isa => File, optional => 0, coerce => 1 }, + ); my $fh = $self->source->openr; seek $fh, $self->offset, 0; my $output = $file->openw; @@ -239,6 +164,8 @@ sub write_to { + + sub contents { my ($self) = @_; my $fh = $self->source->openr; @@ -262,7 +189,7 @@ ELF::Extract::Sections::Section - An Objective reference to a section in an ELF =head1 VERSION -version 1.000000 +version 1.001000 =head1 SYNOPSIS @@ -297,39 +224,27 @@ version 1.000000 Generally Intended for use by L as a meta-structure for tracking data, but generated objects are returned to you for you to deal with -=head1 PUBLIC ATTRIBUTES - -=head2 source - -C|C: Either a String or a Path::Tiny instance pointing to the file in mention. - -=head2 name - -C: The ELF Section Name - -=head2 offset - -C: Position in bytes relative to the start of the file. - -=head2 size - -C: The ELF Section Size +=head1 METHODS -=head1 PUBLIC METHODS +=head2 C -=head2 -> new ( %ATTRIBUTES ) + my $section = ELF::Extract::Sections::Section->new( %ATTRIBUTES ); 4 Parameters, all required. Returns an C object. -=head2 -> to_string +=head2 C + + my $string = $section->to_string; returns C description of the object [ Section {name} of size {size} in {file} @ {start} to {stop} ] -=head2 -> compare ( other => $other, field => $field ) +=head2 C + + my $cmp_result = $section->compare( other => $other, field => $field ); 2 Parameters, both required @@ -347,7 +262,9 @@ C: Field to compare with. returns C of comparison result, between -1 and 1 -=head2 -> write_to ( file => $file ) +=head2 C + + my $boolean = $section->write_to( file => $file ); B @@ -359,10 +276,30 @@ C|C: File target to write section contents to. =back -=head2 -> contents +=head2 C + + my $string = $section->contents; returns C of binary data read out of file. +=head1 ATTRIBUTES + +=head2 C + +C|C: Either a String or a Path::Tiny instance pointing to the file in mention. + +=head2 C + +C: The ELF Section Name + +=head2 C + +C: Position in bytes relative to the start of the file. + +=head2 C + +C: The ELF Section Size + =head1 AUTHOR Kent Fredric diff --git a/maint/perlcritic.rc.gen.pl b/maint/perlcritic.rc.gen.pl index f3d7ec1..3d27b80 100644 --- a/maint/perlcritic.rc.gen.pl +++ b/maint/perlcritic.rc.gen.pl @@ -30,6 +30,7 @@ $bundle->remove_policy('Documentation::RequirePodLinksIncludeText'); $bundle->remove_policy('RegularExpressions::RequireExtendedFormatting'); $bundle->remove_policy('RegularExpressions::RequireDotMatchAnything'); +$bundle->remove_policy('Subroutines::RequireArgUnpacking'); #$bundle->remove_policy('ErrorHandling::RequireCarping'); $bundle->remove_policy('ErrorHandling::RequireUseOfExceptions'); diff --git a/misc/Changes.deps b/misc/Changes.deps index 4be6c51..a39548f 100644 --- a/misc/Changes.deps +++ b/misc/Changes.deps @@ -1,6 +1,14 @@ This file contains changes in REQUIRED dependencies for standard CPAN phases (configure/build/runtime/test) -1.000000 +1.001000 + [Added / runtime requires] + - MooseX::Params::Validate + + [Added / test requires] + - Capture::Tiny + - File::Which + +1.000000 2015-07-30T16:49:16Z [Added / configure requires] - Devel::CheckBin - ExtUtils::MakeMaker diff --git a/misc/Changes.deps.all b/misc/Changes.deps.all index 19fc152..9b4ea38 100644 --- a/misc/Changes.deps.all +++ b/misc/Changes.deps.all @@ -1,6 +1,14 @@ This file contains ALL changes in dependencies in both REQUIRED / OPTIONAL dependencies for all phases (configure/build/runtime/test/develop) -1.000000 +1.001000 + [Added / runtime requires] + - MooseX::Params::Validate + + [Added / test requires] + - Capture::Tiny + - File::Which + +1.000000 2015-07-30T16:49:16Z [Added / configure recommends] - ExtUtils::MakeMaker 7.00 diff --git a/misc/Changes.deps.dev b/misc/Changes.deps.dev index 8d9fa52..f24c48d 100644 --- a/misc/Changes.deps.dev +++ b/misc/Changes.deps.dev @@ -1,6 +1,8 @@ This file contains changes to DEVELOPMENT dependencies only ( both REQUIRED and OPTIONAL ) -1.000000 +1.001000 + +1.000000 2015-07-30T16:49:16Z [Added / develop recommends] - Test::More 0.99 diff --git a/misc/Changes.deps.opt b/misc/Changes.deps.opt index ad2d6cc..3a94e4f 100644 --- a/misc/Changes.deps.opt +++ b/misc/Changes.deps.opt @@ -1,6 +1,8 @@ This file contains changes in OPTIONAL dependencies for standard CPAN phases (configure/build/runtime/test) -1.000000 +1.001000 + +1.000000 2015-07-30T16:49:16Z [Added / configure recommends] - ExtUtils::MakeMaker 7.00 diff --git a/misc/built_with.json b/misc/built_with.json index 8ef3606..485f2b9 100644 --- a/misc/built_with.json +++ b/misc/built_with.json @@ -1,6 +1,7 @@ { "modules" : { "CPAN::Meta" : "2.150005", + "Capture::Tiny" : "0.30", "Carp" : "1.36", "Devel::CheckBin" : "0.03", "Dist::Zilla" : "5.037", @@ -59,6 +60,7 @@ "Dist::Zilla::PluginBundle::Author::KENTNL" : "2.025001", "ExtUtils::MakeMaker" : "7.04_01", "File::Spec" : "3.56", + "File::Which" : "1.18", "FindBin" : "1.51", "Log::Log4perl" : "1.46", "Module::Runtime" : "0.014", @@ -66,6 +68,7 @@ "Moose::Role" : "2.1500", "MooseX::Has::Sugar" : "1.000004", "MooseX::Log::Log4perl" : "0.46", + "MooseX::Params::Validate" : "0.21", "MooseX::Types" : "0.45", "MooseX::Types::Moose" : "0.45", "MooseX::Types::Path::Tiny" : "0.011", @@ -100,5 +103,5 @@ "osname" : "linux" }, "platform" : "linux", - "uname" : "Linux 4.1.0-gentoo-r1 x86_64 GenuineIntel GNU/Linux" + "uname" : "Linux 4.1.4-gentoo x86_64 GenuineIntel GNU/Linux" } diff --git a/perlcritic.rc b/perlcritic.rc index f28fc71..c6c536b 100644 --- a/perlcritic.rc +++ b/perlcritic.rc @@ -336,7 +336,7 @@ private_name_regex = _(?!build_)\w [Subroutines::ProtectPrivateSubs] -[Subroutines::RequireArgUnpacking] +[-Subroutines::RequireArgUnpacking] [Subroutines::RequireFinalReturn] diff --git a/t/00-report-prereqs.dd b/t/00-report-prereqs.dd index 08f158e..a6c5706 100644 --- a/t/00-report-prereqs.dd +++ b/t/00-report-prereqs.dd @@ -92,6 +92,7 @@ do { my $x = { 'Moose::Role' => '0', 'MooseX::Has::Sugar' => '0.0300', 'MooseX::Log::Log4perl' => '0.31', + 'MooseX::Params::Validate' => '0', 'MooseX::Types' => '0.10', 'MooseX::Types::Moose' => '0.10', 'MooseX::Types::Path::Tiny' => '0', @@ -109,8 +110,10 @@ do { my $x = { 'Test::More' => '0.99' }, 'requires' => { + 'Capture::Tiny' => '0', 'ExtUtils::MakeMaker' => '0', 'File::Spec' => '0', + 'File::Which' => '0', 'FindBin' => '0', 'Log::Log4perl' => '1.21', 'Path::Iterator::Rule' => '0', diff --git a/t/00-version-check.t b/t/00-version-check.t new file mode 100644 index 0000000..7dbf390 --- /dev/null +++ b/t/00-version-check.t @@ -0,0 +1,48 @@ +use strict; +use warnings; + +use Test::More; +use File::Which qw( which ); +use Capture::Tiny qw( capture ); + +my $path = which('objdump'); + +unless ( ok( $path, "objdump is available") ) { + done_testing; + exit 0; +}; +{ + my ( $stdout, $stderr, $exit ) = capture { system("objdump --version") }; + + cmp_ok( $exit, '==', 0 , "objdump exited with 0"); + + my $gotoutput = 0; + if ( $stderr !~ /^\s*$/ ) { + diag "STDERR: ---\n" . $stderr; + $gotoutput++; + } + if ( $stdout !~ /^\s*$/ ) { + diag "STDOUT: ---\n" . $stdout; + $gotoutput++; + } + ok( $gotoutput , "objdump --version emitted data" ); +} +{ + my ( $stdout, $stderr, $exit ) = capture { system("objdump --help") }; + + cmp_ok( $exit, '==', 0 , "objdump exited with 0"); + + if ( unlike( $stdout, qr/^\s*$/ , "objdump --help emitted data to STDOUT" ) ) { + + my $ok = like( $stdout, qr/-D,\s*--disassemble-all/, "has -D param" ); + $ok = undef unless like( $stdout, qr/-F,\s*--file-offsets/, "has -F param" ); + + diag "STDOUT: ---\n" . $stdout unless $ok; + } elsif ( $stderr !~ /^\s*$/ ) { + diag "STDERR: ---\n"; + } +} + +done_testing; + + diff --git a/weaver.ini b/weaver.ini index a38b724..2576216 100644 --- a/weaver.ini +++ b/weaver.ini @@ -9,9 +9,6 @@ [Generic / SYNOPSIS] [Generic / DESCRIPTION] -[Generic / NAMING_SCHEME] -header = NAMING SCHEME - [Generic / OVERVIEW] ;[Generic / METHODS] @@ -21,26 +18,6 @@ command = method [Collect / ATTRIBUTES] command = attr -[Collect / FILTER_METHODS] -header = FILTER METHODS -command = filter - -[Collect / TERMINATOR_LIST_METHODS] -header = TERMINATOR LIST METHODS -command = terminator - -[Collect / MIRROR_LIST_METHODS] -header = MIRROR LIST METHODS -command = mirrorlist - -[Collect / PRIVATE_ATTRIBUTES] -header = PRIVATE ATTRIBUTES -command = p_attr - -[Collect / PRIVATE_METHODS] -header = PRIVATE METHODS -command = p_method - [Leftovers] [Region / postlude] diff --git a/xt/author/eol.t b/xt/author/eol.t index 26dfd96..73fcf19 100644 --- a/xt/author/eol.t +++ b/xt/author/eol.t @@ -19,6 +19,7 @@ my @files = ( 't/00-compile/lib_ELF_Extract_Sections_pm.t', 't/00-report-prereqs.dd', 't/00-report-prereqs.t', + 't/00-version-check.t', 't/01-elf-libs.t', 't/test_files/gen_expected.pl' );