aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Delco <delco@chromium.org>2020-02-12 23:05:05 -0800
committerTreehugger Robot <treehugger-gerrit@google.com>2020-02-13 14:01:45 +0000
commitdbb8948ebe348ea4480e17ad397fc1d92b7c8e30 (patch)
treedb0fbef7625dfc5f44ca804ff654a713bb9f2e1b
parentb35f2c18a022f3f2f06869c306a788d9ff361348 (diff)
downloadplatform_external_minijail-dbb8948ebe348ea4480e17ad397fc1d92b7c8e30.tar.gz
platform_external_minijail-dbb8948ebe348ea4480e17ad397fc1d92b7c8e30.tar.bz2
platform_external_minijail-dbb8948ebe348ea4480e17ad397fc1d92b7c8e30.zip
Avoid bextr in dump_constants
When dump_constants is compiled for newer AMD processors it can end up using a bextr instruction that may not be present on other makes/models of processors. The act of calling std::cout on a numeric type ends up in num_put<,>::do_put() which does: const unsigned __nbuf = (numeric_limits<unsigned long>::digits / 3) + ((numeric_limits<unsigned long>::digits % 3) != 0) + ((__iob.flags() & ios_base::showbase) != 0) + 1; ios_base::showbase is 0x0200, so the bit test against showbase results in: bextr $0x109,0x8(%rdx),%r12d which says to extract 1 bit from bit offset 9. A workaround is to use to_string() to avoid passing numeric types to cout. This alternative is straightforward and the implementation is simpler (to_string() does not have formatting nor locale options), though it doesn't prevent the problem from occurring again in the future (e.g., when the source or compiler changes). Bug: None Test: `make tests`. Ran dump_constants on arm32, arm64, and x64 in CrOS build environment. Change-Id: Ic16574141f6c935bff958e5d1f27c81994a993ab
-rw-r--r--dump_constants.cc11
1 files changed, 7 insertions, 4 deletions
diff --git a/dump_constants.cc b/dump_constants.cc
index 80c8664a..f3d70749 100644
--- a/dump_constants.cc
+++ b/dump_constants.cc
@@ -15,10 +15,12 @@
#include "libsyscalls.h"
int main() {
+ // Numeric values are passed to std::cout via std::to_string() to avoid
+ // the use of 'bextr' asm instruction (when compiled with -march=bdver4).
std::cout << "{\n";
- std::cout << " \"arch_nr\": " << MINIJAIL_ARCH_NR << ",\n";
+ std::cout << " \"arch_nr\": " << std::to_string(MINIJAIL_ARCH_NR) << ",\n";
std::cout << " \"arch_name\": \"" << MINIJAIL_ARCH_NAME << "\",\n";
- std::cout << " \"bits\": " << MINIJAIL_ARCH_BITS << ",\n";
+ std::cout << " \"bits\": " << std::to_string(MINIJAIL_ARCH_BITS) << ",\n";
std::cout << " \"syscalls\": {\n";
bool first = true;
for (const struct syscall_entry* entry = syscall_table; entry->name;
@@ -27,7 +29,7 @@ int main() {
first = false;
else
std::cout << ",\n";
- std::cout << " \"" << entry->name << "\": " << entry->nr;
+ std::cout << " \"" << entry->name << "\": " << std::to_string(entry->nr);
}
std::cout << "\n },\n";
std::cout << " \"constants\": {\n";
@@ -38,7 +40,8 @@ int main() {
first = false;
else
std::cout << ",\n";
- std::cout << " \"" << entry->name << "\": " << entry->value;
+ std::cout << " \"" << entry->name << "\": "
+ << std::to_string(entry->value);
}
std::cout << "\n }\n";
std::cout << "}\n";