Last active
February 22, 2018 07:14
-
-
Save iamahuman/12a1f1ae6cc0639393877e3aa063d18f to your computer and use it in GitHub Desktop.
clang wrapper for use with NDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
# NOTE symlinked from NDK, be cautious! | |
use strict; | |
use warnings; | |
use File::Basename; | |
use File::Spec; | |
use File::Copy; | |
our $DEBUG = ''; | |
sub parse_argfile { | |
my ($fh) = @_; | |
my ($st, $arg) = (0, ''); | |
my (@args) = (); | |
for (;;) { | |
my $k = read $fh, my $buf, 1; | |
unless (defined $k) { | |
$_[1] = ''; return; | |
} | |
last unless $k; | |
if ($st < 0) { | |
$st *= -1; | |
$arg .= $buf; | |
} elsif ($buf eq "\\") { | |
$st = -($st || 1); | |
} elsif ($buf eq "\"") { | |
($st == 0 || $st == 1) ? ($st = 2) : | |
($st == 2) ? ($st = 1) : | |
($st == 3) ? ($arg .= $buf) : | |
(die "assert fail"); | |
} elsif ($buf eq "'") { | |
($st == 0 || $st == 1) ? ($st = 3) : | |
($st == 3) ? ($st = 1) : | |
($st == 2) ? ($arg .= $buf) : | |
(die "assert fail"); | |
} elsif ($buf =~ m/\s/) { | |
if ($st == 1) { | |
push @args, $arg; | |
$arg = ''; $st = 0; | |
} elsif ($st >= 2) { | |
$arg .= $buf; | |
} | |
} elsif ($buf ne "") { | |
$st = 1 if $st == 0; | |
$arg .= $buf; | |
} | |
} | |
push @args, $arg if $st != 0; | |
$_[1] = 1; | |
return @args; | |
} | |
our %text_relocs = map {$_ => 1} ( | |
"R_ARM_CALL", | |
"R_ARM_JUMP24", | |
"R_ARM_THM_ABS5", # Direct & 0x7C (LDR, STR). | |
"R_ARM_MOVW_ABS_NC", # Direct 16-bit (MOVW). | |
"R_ARM_MOVT_ABS", # Direct high 16-bit (MOVT). | |
"R_ARM_THM_MOVW_ABS_NC", # Direct 16 bit (Thumb32 MOVW). | |
"R_ARM_THM_MOVT_ABS", # Direct high 16 bit | |
); | |
sub is_not_pic { | |
my ($objdump, $infile) = @_; | |
$infile =~ s#^-#./-#; | |
my $pid = open my $ph, "-|"; | |
return unless defined $pid; | |
unless ($pid) { | |
open STDERR, ">", File::Spec->devnull(); | |
exec {$objdump} $objdump, "-r", $infile; | |
exit 127; | |
} | |
my $res = ''; | |
{ | |
local $/ = "\n"; | |
while (<$ph>) { | |
# FIXME hacky text relocation detection | |
if (m/^\s*[0-9a-fA-F]+\s+(R_\w*)/ && $text_relocs{$1}) { | |
$res = 1; last; | |
} | |
} | |
} | |
close $ph; | |
waitpid $pid, 0; | |
return $res; | |
} | |
sub get_invoke_args { | |
return @ARGV if $#ARGV < 0 || $ARGV[0] eq "-cc1"; | |
my ($nolink, $reloc, $nostdlib, $explicit_pie, $has_input, $skp) = ('')x6; | |
(my $objdump = $0) =~ s/[^-]+$/objdump/ or die "unknown invocation\n"; | |
my @stack = reverse @ARGV; | |
while (@stack) { | |
my $arg = pop @stack; | |
if ($arg =~ m/^@(.+)$/ and open my $fh, "<", $1) { | |
# FIXME May fail if argfile is not a regular file | |
push @stack, reverse parse_argfile($fh, my $ok); | |
close $fh; next if $ok; | |
} | |
warn " ** Argument [$arg]\n" if $DEBUG; | |
$_ = $arg; | |
if ($skp) { | |
$skp = ''; | |
} elsif (!m/^-/) { | |
$has_input = 1; | |
$explicit_pie = -1 if !$explicit_pie && is_not_pic($objdump, $arg); | |
copy($arg, "/tmp/ccwrap-$1") if $DEBUG && $arg =~ m,([^/]+\.s)$,; | |
} elsif (m/^-[oLIDU]$/) { | |
$skp = 1; | |
} elsif (m/^-[cSE]$/) { | |
$nolink = 1; | |
} elsif (m/^-r$/) { | |
$reloc = 1; | |
} elsif (m/^-nostdlib$/) { | |
$nostdlib = 1; | |
} elsif (m/^-(?:nopie|pie|shared|static)$/) { | |
$explicit_pie = 1 if $arg ne "-nopie" || !$explicit_pie; | |
} elsif (m/^-Wl,(.+)$/) { | |
foreach (split /,/, $1) { | |
if (m/^-(?:r|-relocatable)$/) { | |
$reloc = 1; | |
} elsif (m/^-(?:pie|shared|static)$/) { | |
$explicit_pie = 1; | |
} | |
} | |
} | |
} | |
warn "\n" if $DEBUG; | |
$nolink ||= !$has_input; | |
warn " ** Detected a non-PIC object as input; switching to -static **\n" | |
if !$nolink && !$reloc && $explicit_pie eq -1; | |
return (qw(-target armv7a-none-linux-androideabi), | |
"--sysroot", (dirname($0) . "/../sysroot"), | |
qw(-D__ANDROID_API__=24), | |
qw(-fPIC -mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16), | |
($nolink ? () : "-Wl,--fix-cortex-a8"), | |
($nolink || $reloc || $explicit_pie eq 1 ? () : ($explicit_pie eq -1 ? "-static" : "-pie")), | |
@ARGV, | |
($nolink || $reloc || $nostdlib ? () : "-lluke1337-android-support")); | |
} | |
unless (defined caller) { | |
my $exe = dirname($0) . ($0 =~ m/\+\+$/ ? "/clang50++" : "/clang50"); | |
exec {$exe} $exe, get_invoke_args(); | |
exit 127; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment