forked from linuxkerneltravel/lmp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update and add more code comments (linuxkerneltravel#538)
* [doc] update test_bench and README * [doc] update and add more code comments * [chore] update miscs
- Loading branch information
Showing
30 changed files
with
799 additions
and
674 deletions.
There are no files selected for viewing
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,3 +3,4 @@ doc/ | |
vmlinux/vmlinux.h | ||
*.out | ||
*.data/ | ||
utrace.data |
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,59 +14,59 @@ | |
// | ||
// author: [email protected] | ||
// | ||
// demangle mangled C++ symbols | ||
// demangle and simplify mangled C++ symbols | ||
|
||
#include "demangle.h" | ||
|
||
#include <stdio.h> // for perror | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#include "util.h" | ||
|
||
// simplify the demangled symbol name | ||
/** | ||
* @brief simplify the demangled symbol name | ||
*/ | ||
static char *simplify(char *name) { | ||
size_t len = strlen(name); | ||
if (!len) return name; | ||
|
||
// remove function template "<...>" | ||
// remove all function templates, i.e., "<...>" | ||
for (size_t i = 0; i < len; i++) { | ||
if (name[i] == '<') { | ||
if (name[i + 1] == '<' && i >= 8 && | ||
strncmp(name + i - 8, "operator", 8) == 0) { // skip operator<< | ||
i++; | ||
if (i >= 8 && !strncmp(name + i - 8, "operator", 8)) { // skip `operator<` and `operator<<` | ||
if (name[i + 1] == '<') ++i; | ||
// remove useless extra blanks | ||
size_t j = i + 1; | ||
while (name[j] == ' ') ++j; | ||
memmove(name + i + 1, name + j, len - j + 1); | ||
len -= j - i - 1; | ||
continue; | ||
} | ||
size_t j = i; | ||
int nested = 1; | ||
while (j + 1 < len) { | ||
++j; | ||
if (name[j] == '<') { | ||
++nested; | ||
} else if (name[j] == '>') { | ||
--nested; | ||
if (!nested) break; | ||
} else { | ||
size_t j = i; | ||
int nested = 1; | ||
while (j + 1 < len) { | ||
++j; | ||
if (name[j] == '<') { | ||
++nested; | ||
} else if (name[j] == '>') { | ||
--nested; | ||
if (!nested) break; | ||
} | ||
} | ||
memmove(name + i, name + j + 1, len - j); | ||
len -= j - i + 1; | ||
} | ||
memmove(name + i, name + j + 1, len - j); | ||
len -= j - i + 1; | ||
} | ||
} | ||
|
||
// remove function cv-qualifier | ||
// remove the last function cv-qualifier | ||
for (size_t i = len - 1; i > 0; i--) { | ||
if (name[i] == ')') break; | ||
if (name[i] == ' ' && name[i - 1] == ')') { | ||
name[i] = '\0'; | ||
len = i; | ||
name[len = i] = '\0'; | ||
break; | ||
} | ||
} | ||
|
||
// remove lambda function parameters, i.e., {lambda(...)} | ||
// remove all lambda function parameters, i.e., "{lambda(...)}" | ||
for (size_t i = 0; i < len; i++) { | ||
if (strncmp(name + i, "{lambda", 7) == 0) { | ||
i += 7; // name[i] == '(' | ||
|
@@ -83,11 +83,10 @@ static char *simplify(char *name) { | |
} | ||
memmove(name + i, name + j + 1, len - j); | ||
len -= j - i + 1; | ||
break; | ||
} | ||
} | ||
|
||
// remove function parameters, i.e., the last "(...)" | ||
// remove all function parameters, i.e., "(...)" | ||
for (size_t i = len - 1; i > 0; i--) { | ||
if (name[i] == ')') { | ||
size_t j = i; | ||
|
@@ -103,48 +102,64 @@ static char *simplify(char *name) { | |
} | ||
memmove(name + i, name + j + 1, len - j); | ||
len -= j - i + 1; | ||
// remove function return type | ||
for (j = i; j > 0; j--) { | ||
if (name[j] == ' ') { | ||
if (j != 8 || strncmp(name, "operator", 8)) { | ||
for (j = i - 1; j > 0; j--) { | ||
if (name[j] == ':' && name[j + 1] == ':') { // there may be nested lambdas or namespaces | ||
i = j - 1; | ||
while (i > 0 && name[i] != ')' && name[i] != ':') --i; | ||
if (name[i] == ')') { | ||
if (!strncmp(name + i + 1, " const", 6)) { // remove function cv-qualifier | ||
memmove(name + i + 1, name + j, len - j + 1); | ||
len -= j - i - 1; | ||
} | ||
break; | ||
} | ||
} else if (name[j] == ' ') { // remove function return type at the beginning | ||
if (!(j == 8 && !strncmp(name, "operator", 8))) { | ||
memmove(name, name + j + 1, len - j); | ||
len -= j + 1; | ||
} | ||
i = 0; | ||
break; | ||
} | ||
} | ||
break; | ||
++i; | ||
} | ||
} | ||
|
||
// remove trailing space | ||
while (len >= 1 && name[len - 1] == ' ') --len; | ||
|
||
// remove trailing spaces | ||
while (len >= 1 && name[len - 1] == ' ') name[--len] = '\0'; | ||
if (name[0] == '(' && name[len - 1] == ')') { | ||
memmove(name, name + 1, len); | ||
name[len - 2] = '\0'; | ||
return simplify(name); | ||
} | ||
int st = 0; | ||
while (name[st] == '*' || name[st] == '&') ++st; | ||
if (st) memmove(name, name + st, len - st + 1); | ||
return name; | ||
} | ||
|
||
char *demangle(const char *mangled_name) { | ||
const char *GLOBAL_PREFIX = "_GLOBAL__sub_I_"; | ||
const size_t LEN = 15; | ||
|
||
char *demangled_name; | ||
size_t demangled_len; | ||
int status; | ||
size_t offset = 0; | ||
|
||
// handle symbols starting with GLOBAL_PREFIX introduced by <iostream> | ||
if (strncmp(mangled_name, GLOBAL_PREFIX, LEN) == 0) offset = LEN; | ||
// handle symbols starting with `GLOBAL_PREFIX` introduced by <iostream> | ||
const char *GLOBAL_PREFIX = "_GLOBAL__sub_I_"; | ||
const size_t LEN = 15; | ||
if (!strncmp(mangled_name, GLOBAL_PREFIX, LEN)) offset = LEN; | ||
|
||
// ensure mangled_name is really mangled (start with "_Z") | ||
if (strncmp(mangled_name + offset, "_Z", 2) == 0) { | ||
// ensure `mangled_name` is really mangled (start with "_Z") | ||
if (!strncmp(mangled_name + offset, "_Z", 2)) { | ||
demangled_name = __cxa_demangle(mangled_name + offset, NULL, NULL, &status); | ||
if (!status) { | ||
demangled_name = simplify(demangled_name); | ||
demangled_len = strlen(demangled_name); | ||
if (offset > 0) { | ||
if (offset > 0) { // concat `GLOBAL_PREFIX` with `demangled_name` | ||
demangled_name = realloc(demangled_name, demangled_len + 1 + LEN); | ||
if (!demangled_name) die("realloc"); | ||
memmove(demangled_name + LEN, demangled_name, demangled_len + 1); | ||
memmove(demangled_name + LEN, demangled_name, demangled_len + 1); // keep the last '\0' | ||
memcpy(demangled_name, GLOBAL_PREFIX, LEN); | ||
} | ||
return demangled_name; | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,24 +14,21 @@ | |
// | ||
// author: [email protected] | ||
// | ||
// demangle mangled C++ symbols | ||
// demangle and simplify mangled C++ symbols | ||
|
||
#ifndef UTRACE_DEMANGLE_H | ||
#define UTRACE_DEMANGLE_H | ||
|
||
#include <stddef.h> | ||
#include <stddef.h> // for size_t | ||
|
||
// defined in libstdc++ | ||
extern char *__cxa_demangle(const char *mangled_name, char *output_buffer, size_t *length, | ||
int *status); | ||
|
||
/** | ||
* @brief 还原重整符号 | ||
* @param[in] mangled_name 符号 | ||
* @return 还原后的符号 | ||
* @details 对于未重整的符号,调用strdup() | ||
* 对于重整过的符号(以"_Z"起始),调用abi::__cxa_demangle() | ||
* @retval 指向堆内存 | ||
* @brief demangle and simplify the `mangled_name` | ||
* @return demangled name malloced from heap | ||
*/ | ||
char *demangle(const char *mangled_name); | ||
|
||
#endif // UTRACE_DEMANGLE_H | ||
#endif // UTRACE_DEMANGLE_H |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,7 +14,7 @@ | |
// | ||
// author: [email protected] | ||
// | ||
// 解析ELF格式以遍历ELF中的各个节以及符号节中的各个条目 | ||
// Use gelf library to parse each section in an ELF file | ||
|
||
#include "elf.h" | ||
|
||
|
@@ -31,7 +31,6 @@ bool elf_head_init(struct elf_head *elf, const char *filename) { | |
if (!elf->e) return false; | ||
|
||
if (elf_kind(elf->e) != ELF_K_ELF) return false; | ||
|
||
if (!gelf_getehdr(elf->e, &elf->ehdr)) return false; | ||
|
||
return true; | ||
|
@@ -47,7 +46,7 @@ void elf_head_free(struct elf_head *elf) { | |
size_t get_entry_address(const char *filename) { | ||
struct elf_head elf; | ||
if (!elf_head_init(&elf, filename)) return 0; | ||
size_t entry = elf.ehdr.e_entry; | ||
size_t entry = elf.ehdr.e_entry; // the entry address is recorded in ELF header | ||
elf_head_free(&elf); | ||
return entry; | ||
} | ||
|
@@ -64,13 +63,14 @@ bool elf_section_next(struct elf_section *elf_s, struct elf_head *elf) { | |
|
||
void elf_sym_entry_begin(struct elf_sym_entry *elf_e, struct elf_section *elf_s) { | ||
elf_e->i = 0; | ||
elf_e->nentries = elf_s->shdr.sh_size / elf_s->shdr.sh_entsize; | ||
elf_e->nentries = | ||
elf_s->shdr.sh_size / elf_s->shdr.sh_entsize; // number of entries in this section | ||
elf_e->sym_data = elf_getdata(elf_s->scn, NULL); | ||
elf_e->str_idx = elf_s->shdr.sh_link; | ||
} | ||
|
||
bool elf_sym_entry_next(struct elf_sym_entry *elf_e, struct elf_section *elf_s) { | ||
(void)elf_s; | ||
(void)elf_s; // keep all functions' prototypes consistent | ||
if (elf_e->i >= elf_e->nentries) return false; | ||
gelf_getsym(elf_e->sym_data, elf_e->i, &elf_e->sym); | ||
elf_e->i++; | ||
|
Oops, something went wrong.