am acc6bb23: am 14a1c8bc: am 6d7bf89b: am 70fe8131: am 05941516: am b7397e97: am 639e319b: am 49869d92: Add a CTS test to detect unsupported ABIs.

* commit 'acc6bb239d636b00d744cd9dd1908fe8912abe4b':
  Add a CTS test to detect unsupported ABIs.
diff --git a/tests/tests/security/src/android/security/cts/ReadElf.java b/tests/src/android/os/cts/ReadElf.java
similarity index 91%
rename from tests/tests/security/src/android/security/cts/ReadElf.java
rename to tests/src/android/os/cts/ReadElf.java
index 2266b8b..b43fd36 100644
--- a/tests/tests/security/src/android/security/cts/ReadElf.java
+++ b/tests/src/android/os/cts/ReadElf.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.security.cts;
+package android.os.cts;
 
 import java.io.File;
 import java.io.IOException;
@@ -26,12 +26,19 @@
  * A poor man's implementation of the readelf command. This program is
  * designed to parse ELF (Executable and Linkable Format) files.
  */
-class ReadElf {
+public class ReadElf {
     /** The magic values for the ELF identification. */
     private static final byte[] ELF_IDENT = {
             (byte) 0x7F, (byte) 'E', (byte) 'L', (byte) 'F',
     };
 
+    private static final int EI_CLASS = 4;
+    private static final int EI_DATA = 5;
+
+    private static final int EM_386 = 3;
+    private static final int EM_MIPS = 8;
+    private static final int EM_ARM = 40;
+
     /** Size of the e_ident[] structure in the ELF header. */
     private static final int EI_NIDENT = 16;
 
@@ -179,9 +186,9 @@
         }
     };
 
+    private final String mPath;
     private final RandomAccessFile mFile;
     private final byte[] mBuffer = new byte[512];
-    private int mClass;
     private int mEndian;
     private boolean mIsDynamic;
     private boolean mIsPIE;
@@ -225,23 +232,24 @@
     /** Dynamic Symbol Table symbol names */
     private Map<String, Symbol> mDynamicSymbols;
 
-    static ReadElf read(File file) throws IOException {
+    public static ReadElf read(File file) throws IOException {
         return new ReadElf(file);
     }
 
-    boolean isDynamic() {
+    public boolean isDynamic() {
         return mIsDynamic;
     }
 
-    int getType() {
+    public int getType() {
         return mType;
     }
 
-    boolean isPIE() {
+    public boolean isPIE() {
         return mIsPIE;
     }
 
     private ReadElf(File file) throws IOException {
+        mPath = file.getPath();
         mFile = new RandomAccessFile(file, "r");
 
         readIdent();
@@ -261,6 +269,10 @@
 
     private void readHeader() throws IOException {
         mType = readHalf(getHeaderOffset(OFFSET_TYPE));
+        int e_machine = readHalf(getHeaderOffset(OFFSET_MACHINE));
+        if (e_machine != EM_386 && e_machine != EM_MIPS && e_machine != EM_ARM) {
+            throw new IOException("Invalid ELF e_machine: " + e_machine + ": " + mPath);
+        }
 
         final long shOffset = readWord(getHeaderOffset(OFFSET_SHOFF));
         final int shNumber = readHalf(getHeaderOffset(OFFSET_SHNUM));
@@ -441,18 +453,26 @@
 
         if ((mBuffer[0] != ELF_IDENT[0]) || (mBuffer[1] != ELF_IDENT[1])
                 || (mBuffer[2] != ELF_IDENT[2]) || (mBuffer[3] != ELF_IDENT[3])) {
-            throw new IllegalArgumentException("Invalid ELF file");
+            throw new IllegalArgumentException("Invalid ELF file: " + mPath);
         }
 
-        mClass = mBuffer[4];
-        if (mClass == ELFCLASS32) {
+        int elfClass = mBuffer[EI_CLASS];
+        if (elfClass == ELFCLASS32) {
             mWordSize = 4;
             mHalfWordSize = 2;
+        } else if (elfClass == ELFCLASS64) {
+            throw new IOException("Unsupported ELFCLASS64 file: " + mPath);
         } else {
-            throw new IOException("Invalid executable type " + mClass + ": not ELFCLASS32!");
+            throw new IOException("Invalid ELF EI_CLASS: " + elfClass + ": " + mPath);
         }
 
-        mEndian = mBuffer[5];
+        mEndian = mBuffer[EI_DATA];
+        if (mEndian == ELFDATA2LSB) {
+        } else if (mEndian == ELFDATA2MSB) {
+            throw new IOException("Unsupported ELFDATA2MSB file: " + mPath);
+        } else {
+            throw new IOException("Invalid ELF EI_DATA: " + mEndian + ": " + mPath);
+        }
     }
 
     public Symbol getSymbol(String name) {
diff --git a/tests/tests/os/src/android/os/cts/AbiTest.java b/tests/tests/os/src/android/os/cts/AbiTest.java
new file mode 100644
index 0000000..69b314dc
--- /dev/null
+++ b/tests/tests/os/src/android/os/cts/AbiTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.cts;
+
+import android.os.cts.ReadElf;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+public class AbiTest extends TestCase {
+    public void testNo64() throws Exception {
+        for (String dir : new File("/").list()) {
+            if (!dir.equals("data") && !dir.equals("dev") && !dir.equals("proc") && !dir.equals("sys")) {
+                checkElfFilesInDirectory(new File("/" + dir));
+            }
+        }
+    }
+
+    private void checkElfFilesInDirectory(File dir) throws Exception {
+        if (!dir.isDirectory()) {
+            return;
+        }
+
+        if (isSymbolicLink(dir)) {
+            return;
+        }
+
+        File[] files = dir.listFiles();
+        if (files == null) {
+            return;
+        }
+
+        for (File f : files) {
+            if (f.isDirectory()) {
+                checkElfFilesInDirectory(f);
+            } else if (f.getName().endsWith(".so") || f.canExecute()) {
+                try {
+                    ReadElf.read(f);
+                } catch (IllegalArgumentException ignored) {
+                    // If it's not actually an ELF file, we don't care.
+                }
+            }
+        }
+    }
+
+    private static boolean isSymbolicLink(File f) throws Exception {
+        return !f.getAbsolutePath().equals(f.getCanonicalPath());
+    }
+}
diff --git a/tests/tests/security/src/android/security/cts/AslrTest.java b/tests/tests/security/src/android/security/cts/AslrTest.java
index a4c4f80..1e76d90 100644
--- a/tests/tests/security/src/android/security/cts/AslrTest.java
+++ b/tests/tests/security/src/android/security/cts/AslrTest.java
@@ -24,6 +24,8 @@
 import java.io.FileReader;
 import java.io.IOException;
 
+import android.os.cts.ReadElf;
+
 /**
  * Verify that ASLR is properly enabled on Android Compatible devices.
  */