END blocks are executed in the reverse order they are encountered. So if you put an END block right at the top of your program that sets $?, you should be set.
my $rv = 2; # assume fatal.
END { $? = $rv; }
use ...
use ...
{
...
if (...) { $rv = 1; exit(); }
...
$rv = 0;
}