Skip to content

Commit 983fc71

Browse files
committed
support for separate debug info: build-ids
1 parent f6a7853 commit 983fc71

File tree

2 files changed

+68
-13
lines changed

2 files changed

+68
-13
lines changed

elf_parser.cpp

Lines changed: 61 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
// SOFTWARE.
2222

2323
#include "elf_parser.hpp"
24+
#include <sys/stat.h>
25+
#include <cstring>
2426
using namespace elf_parser;
2527

2628
std::vector<section_t> Elf_parser::get_sections() {
@@ -80,23 +82,53 @@ std::vector<symbol_t> Elf_parser::get_symbols() {
8082
// get headers for offsets
8183
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)m_mmap_program;
8284
Elf64_Shdr *shdr = (Elf64_Shdr*)(m_mmap_program + ehdr->e_shoff);
83-
85+
// get build-id
86+
char *build_id_buf = nullptr;
87+
std::string buildId;
8488
// get strtab
8589
char *sh_strtab_p = nullptr;
86-
for(auto &sec: secs) {
87-
if((sec.section_type == "SHT_STRTAB") && (sec.section_name == ".strtab")){
88-
sh_strtab_p = (char*)m_mmap_program + sec.section_offset;
89-
break;
90-
}
91-
}
92-
9390
// get dynstr
9491
char *sh_dynstr_p = nullptr;
95-
for(auto &sec: secs) {
96-
if((sec.section_type == "SHT_STRTAB") && (sec.section_name == ".dynstr")){
97-
sh_dynstr_p = (char*)m_mmap_program + sec.section_offset;
98-
break;
92+
for (auto &sec : secs) {
93+
if ((sec.section_type == "SHT_NOTE") &&
94+
(sec.section_name == ".note.gnu.build-id")) {
95+
build_id_buf =
96+
reinterpret_cast<char *>(m_mmap_program) + sec.section_offset;
97+
98+
Elf64_Nhdr *nhdr64 = reinterpret_cast<Elf64_Nhdr *>(build_id_buf);
99+
100+
uint64_t n_namesz = nhdr64->n_namesz;
101+
uint64_t n_descsz = nhdr64->n_descsz;
102+
uint64_t n_type = nhdr64->n_type;
103+
char *n_data = build_id_buf + sizeof(Elf64_Nhdr);
104+
105+
if (std::strcmp(n_data, ELF_NOTE_GNU) == 0 &&
106+
n_type == NT_GNU_BUILD_ID) {
107+
const char *hex_digits = "0123456789abcdef";
108+
unsigned char *build_id;
109+
110+
build_id = (unsigned char *)n_data + n_namesz;
111+
for (int i = 0; i < n_descsz; i++) {
112+
buildId.push_back(hex_digits[(build_id[i] >> 4) & 0xf]);
113+
buildId.push_back(hex_digits[(build_id[i] >> 0) & 0xf]);
114+
}
99115
}
116+
}
117+
118+
if ((sec.section_type == "SHT_STRTAB") &&
119+
(sec.section_name == ".strtab")) {
120+
sh_strtab_p =
121+
reinterpret_cast<char *>(m_mmap_program) + sec.section_offset;
122+
}
123+
124+
if ((sec.section_type == "SHT_STRTAB") &&
125+
(sec.section_name == ".dynstr")) {
126+
sh_dynstr_p =
127+
reinterpret_cast<char *>(m_mmap_program) + sec.section_offset;
128+
}
129+
if (build_id_buf && sh_strtab_p && sh_dynstr_p) {
130+
break;
131+
}
100132
}
101133

102134
std::vector<symbol_t> symbols;
@@ -127,6 +159,23 @@ std::vector<symbol_t> Elf_parser::get_symbols() {
127159
symbols.push_back(symbol);
128160
}
129161
}
162+
163+
if (buildId.length() > 0) {
164+
/* Look for separate debug info: build-ids */
165+
std::string debug_file =
166+
std::string("/usr/lib/debug/.build-id/" + buildId.substr(0, 2) + "/" +
167+
buildId.substr(2, std::string::npos) + ".debug");
168+
169+
if (m_program_path != debug_file) {
170+
struct stat buffer;
171+
if (stat(debug_file.c_str(), &buffer) == 0) {
172+
Elf_parser dp(debug_file.c_str());
173+
auto debug_syms = dp.get_symbols();
174+
symbols.insert(symbols.end(), debug_syms.begin(), debug_syms.end());
175+
}
176+
}
177+
}
178+
130179
return symbols;
131180
}
132181

elf_parser.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,16 @@ typedef struct {
6363
std::intptr_t relocation_plt_address;
6464
} relocation_t;
6565

66+
// Note header for ELF64.
67+
struct Elf64_Nhdr {
68+
Elf64_Word n_namesz;
69+
Elf64_Word n_descsz;
70+
Elf64_Word n_type;
71+
};
6672

6773
class Elf_parser {
6874
public:
69-
Elf_parser (std::string &program_path): m_program_path{program_path} {
75+
Elf_parser (const std::string &program_path): m_program_path{program_path} {
7076
load_memory_map();
7177
}
7278
std::vector<section_t> get_sections();

0 commit comments

Comments
 (0)