update_engine: Use constants from elf.h.
This patch changes GetFileFormatELF() to use the constants from elf.h
and includes the mips architecture.
BUG=chromium:401873
TEST=FEATURES=test emerge-link update_engine
Change-Id: I4d2924f121cd56dc80b8099b46f4456ebb3dfefc
Reviewed-on: https://chromium-review.googlesource.com/211662
Reviewed-by: Alex Deymo <[email protected]>
Commit-Queue: Alex Deymo <[email protected]>
Tested-by: Alex Deymo <[email protected]>
Reviewed-by: Mike Frysinger <[email protected]>
diff --git a/utils.cc b/utils.cc
index f69dab4..2c17be8 100644
--- a/utils.cc
+++ b/utils.cc
@@ -8,6 +8,7 @@
#include <attr/xattr.h>
#include <dirent.h>
+#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
@@ -696,18 +697,18 @@
// description of it on the |output| string.
static bool GetFileFormatELF(const char* buffer, size_t size, string* output) {
// 0x00: EI_MAG - ELF magic header, 4 bytes.
- if (size < 4 || memcmp(buffer, "\x7F""ELF", 4) != 0)
+ if (size < SELFMAG || memcmp(buffer, ELFMAG, SELFMAG) != 0)
return false;
*output = "ELF";
// 0x04: EI_CLASS, 1 byte.
- if (size < 0x04 + 1)
+ if (size < EI_CLASS + 1)
return true;
- switch (buffer[4]) {
- case 1:
+ switch (buffer[EI_CLASS]) {
+ case ELFCLASS32:
*output += " 32-bit";
break;
- case 2:
+ case ELFCLASS64:
*output += " 64-bit";
break;
default:
@@ -715,14 +716,14 @@
}
// 0x05: EI_DATA, endianness, 1 byte.
- if (size < 0x05 + 1)
+ if (size < EI_DATA + 1)
return true;
- char ei_data = buffer[5];
+ char ei_data = buffer[EI_DATA];
switch (ei_data) {
- case 1:
+ case ELFDATA2LSB:
*output += " little-endian";
break;
- case 2:
+ case ELFDATA2MSB:
*output += " big-endian";
break;
default:
@@ -731,24 +732,29 @@
return true;
}
- // 0x12: e_machine, 2 byte endianness based on ei_data
- if (size < 0x12 + 2)
+ const Elf32_Ehdr* hdr = reinterpret_cast<const Elf32_Ehdr*>(buffer);
+ // 0x12: e_machine, 2 byte endianness based on ei_data. The position (0x12)
+ // and size is the same for both 32 and 64 bits.
+ if (size < offsetof(Elf32_Ehdr, e_machine) + sizeof(hdr->e_machine))
return true;
- uint16_t e_machine = *reinterpret_cast<const uint16_t*>(buffer+0x12);
+ uint16_t e_machine;
// Fix endianess regardless of the host endianess.
- if (ei_data == 1)
- e_machine = le16toh(e_machine);
+ if (ei_data == ELFDATA2LSB)
+ e_machine = le16toh(hdr->e_machine);
else
- e_machine = be16toh(e_machine);
+ e_machine = be16toh(hdr->e_machine);
switch (e_machine) {
- case 0x03:
+ case EM_386:
*output += " x86";
break;
- case 0x28:
+ case EM_MIPS:
+ *output += " mips";
+ break;
+ case EM_ARM:
*output += " arm";
break;
- case 0x3E:
+ case EM_X86_64:
*output += " x86-64";
break;
default:
diff --git a/utils_unittest.cc b/utils_unittest.cc
index aa1f919..53e4428 100644
--- a/utils_unittest.cc
+++ b/utils_unittest.cc
@@ -11,8 +11,8 @@
#include <string>
#include <vector>
-#include <base/files/file_path.h>
#include <base/file_util.h>
+#include <base/files/file_path.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>
@@ -380,6 +380,14 @@
0x02, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00,
0x90, 0x83, 0x04, 0x08, 0x34, 0x00, 0x00, 0x00});
+ // ELF 32-bit LSB executable, MIPS
+ GetFileFormatTester(
+ "ELF 32-bit little-endian mips",
+ vector<uint8_t>{0x7f, 0x45, 0x4c, 0x46, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
+ 0xc0, 0x12, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00});
+
// ELF 32-bit LSB executable, ARM
GetFileFormatTester(
"ELF 32-bit little-endian arm",