Merge "Simpleperf: add option to report branch stack information."
diff --git a/simpleperf/read_elf.cpp b/simpleperf/read_elf.cpp
index 5fb94e5..4d41165 100644
--- a/simpleperf/read_elf.cpp
+++ b/simpleperf/read_elf.cpp
@@ -32,10 +32,11 @@
#pragma clang diagnostic pop
-#include <elf.h>
-
#include "utils.h"
+#define ELF_NOTE_GNU "GNU"
+#define NT_GNU_BUILD_ID 3
+
static bool GetBuildIdFromNoteSection(const char* section, size_t section_size, BuildId* build_id) {
const char* p = section;
const char* end = p + section_size;
@@ -77,7 +78,7 @@
bool GetBuildIdFromELFFile(const llvm::object::ELFFile<ELFT>* elf, BuildId* build_id) {
for (auto section_iterator = elf->begin_sections(); section_iterator != elf->end_sections();
++section_iterator) {
- if (section_iterator->sh_type == SHT_NOTE) {
+ if (section_iterator->sh_type == llvm::ELF::SHT_NOTE) {
auto contents = elf->getSectionContents(&*section_iterator);
if (contents.getError()) {
LOG(DEBUG) << "read note section error";
@@ -114,10 +115,19 @@
}
return result;
}
+
+bool IsArmMappingSymbol(const char* name) {
+ // Mapping symbols in arm, which are described in "ELF for ARM Architecture" and
+ // "ELF for ARM 64-bit Architecture". The regular expression to match mapping symbol
+ // is ^\$(a|d|t|x)(\..*)?$
+ return name[0] == '$' && strchr("adtx", name[1]) != nullptr && (name[2] == '\0' || name[2] == '.');
+}
+
template <class ELFT>
bool ParseSymbolsFromELFFile(const llvm::object::ELFFile<ELFT>* elf,
std::function<void(const ElfFileSymbol&)> callback) {
- bool is_arm = (elf->getHeader()->e_machine == EM_ARM);
+ bool is_arm = (elf->getHeader()->e_machine == llvm::ELF::EM_ARM ||
+ elf->getHeader()->e_machine == llvm::ELF::EM_AARCH64);
auto begin = elf->begin_symbols();
auto end = elf->end_symbols();
if (begin == end) {
@@ -158,16 +168,17 @@
}
symbol.len = elf_symbol.st_size;
int type = elf_symbol.getType();
- if (type == STT_FUNC) {
+ if (type == llvm::ELF::STT_FUNC) {
symbol.is_func = true;
- } else if (type == STT_NOTYPE) {
+ } else if (type == llvm::ELF::STT_NOTYPE) {
if (symbol.is_in_text_section) {
symbol.is_label = true;
-
- // Arm has meaningless labels like $t, $d, $x, exclude them.
if (is_arm) {
- size_t test_pos = (symbol.name.find(linker_prefix) == 0) ? linker_prefix.size() : 0;
- if (test_pos + 2 == symbol.name.size() && symbol.name[test_pos] == '$') {
+ // Remove mapping symbols in arm.
+ const char* p = (symbol.name.compare(0, linker_prefix.size(), linker_prefix) == 0)
+ ? symbol.name.c_str() + linker_prefix.size()
+ : symbol.name.c_str();
+ if (IsArmMappingSymbol(p)) {
symbol.is_label = false;
}
}
diff --git a/simpleperf/read_elf.h b/simpleperf/read_elf.h
index 487fc28..96eb2f3 100644
--- a/simpleperf/read_elf.h
+++ b/simpleperf/read_elf.h
@@ -39,4 +39,7 @@
bool ParseSymbolsFromElfFile(const std::string& filename,
std::function<void(const ElfFileSymbol&)> callback);
+// Expose the following functions for unit tests.
+bool IsArmMappingSymbol(const char* name);
+
#endif // SIMPLE_PERF_READ_ELF_H_
diff --git a/simpleperf/read_elf_test.cpp b/simpleperf/read_elf_test.cpp
index bc9ef73..c0ff660 100644
--- a/simpleperf/read_elf_test.cpp
+++ b/simpleperf/read_elf_test.cpp
@@ -36,3 +36,10 @@
ParseSymbolsFromElfFile(elf_file, std::bind(ParseSymbol, std::placeholders::_1, &result)));
ASSERT_TRUE(result);
}
+
+TEST(read_elf, arm_mapping_symbol) {
+ ASSERT_TRUE(IsArmMappingSymbol("$a"));
+ ASSERT_FALSE(IsArmMappingSymbol("$b"));
+ ASSERT_TRUE(IsArmMappingSymbol("$a.anything"));
+ ASSERT_FALSE(IsArmMappingSymbol("$a_no_dot"));
+}
diff --git a/squashfs_utils/mksquashfsimage.sh b/squashfs_utils/mksquashfsimage.sh
index 7f96cb1..dab80ba 100755
--- a/squashfs_utils/mksquashfsimage.sh
+++ b/squashfs_utils/mksquashfsimage.sh
@@ -5,7 +5,7 @@
function usage() {
cat<<EOT
Usage:
-${0##*/} SRC_DIR OUTPUT_FILE [-m MOUNT_POINT] [-c FILE_CONTEXTS] [-b BLOCK_SIZE]
+${0##*/} SRC_DIR OUTPUT_FILE [-s] [-m MOUNT_POINT] [-c FILE_CONTEXTS] [-b BLOCK_SIZE]
EOT
}
@@ -24,6 +24,12 @@
OUTPUT_FILE=$2
shift; shift
+SPARSE=false
+if [[ "$1" == "-s" ]]; then
+ SPARSE=true
+ shift;
+fi
+
MOUNT_POINT=
if [[ "$1" == "-m" ]]; then
MOUNT_POINT=$2
@@ -53,9 +59,20 @@
OPT="$OPT -b $BLOCK_SIZE"
fi
-MAKE_SQUASHFS_CMD="mksquashfs $SRC_DIR $OUTPUT_FILE -no-progress -comp lz4 -Xhc -no-exports -noappend -no-recovery -android-fs-config $OPT"
+MAKE_SQUASHFS_CMD="mksquashfs $SRC_DIR/ $OUTPUT_FILE -no-progress -comp lz4 -Xhc -no-exports -noappend -no-recovery -android-fs-config $OPT"
echo $MAKE_SQUASHFS_CMD
$MAKE_SQUASHFS_CMD
+
if [ $? -ne 0 ]; then
exit 4
fi
+
+SPARSE_SUFFIX=".sparse"
+if [ "$SPARSE" = true ]; then
+ img2simg $OUTPUT_FILE $OUTPUT_FILE$SPARSE_SUFFIX
+ if [ $? -ne 0 ]; then
+ exit 4
+ fi
+ mv $OUTPUT_FILE$SPARSE_SUFFIX $OUTPUT_FILE
+fi
+
diff --git a/tests/net_test/multinetwork_base.py b/tests/net_test/multinetwork_base.py
index 8940258..5952d56 100644
--- a/tests/net_test/multinetwork_base.py
+++ b/tests/net_test/multinetwork_base.py
@@ -430,13 +430,12 @@
raise ValueError("Unknown interface selection mode %s" % mode)
def BuildSocket(self, version, constructor, netid, routing_mode):
- uid = self.UidForNetid(netid) if routing_mode == "uid" else None
- with net_test.RunAsUid(uid):
- family = self.GetProtocolFamily(version)
- s = constructor(family)
+ s = constructor(self.GetProtocolFamily(version))
if routing_mode not in [None, "uid"]:
self.SelectInterface(s, netid, routing_mode)
+ elif routing_mode == "uid":
+ os.fchown(s.fileno(), self.UidForNetid(netid), -1)
return s