28 #include "../common/common.h"
33 void output_init (
struct output_buffer* ob,
char*
buf,
size_t sz)
41 void output_print (
struct output_buffer* ob,
const char*
format, ...)
44 if (ob->sz == ob->ptr)
46 ob->buf[ob->ptr] =
'\0';
48 vsnprintf(ob->buf + ob->ptr, ob->sz - ob->ptr, format, ap);
51 ob->ptr = strlen(ob->buf + ob->ptr) + ob->ptr;
54 static void lookup_section (bfd* abfd, asection* sec,
void* opaque_data)
56 struct find_info*
data = (
struct find_info*)opaque_data;
61 if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
64 const bfd_vma vma = bfd_get_section_vma(abfd, sec);
65 if (data->counter < vma || vma + bfd_get_section_size(sec) <= data->counter)
68 bfd_find_nearest_line(abfd, sec, data->symbol, data->counter - vma,
69 &(data->file), &(data->func), &(data->line));
72 void find (
struct bfd_ctx * b,
size_t offset,
const char** file,
const char** func,
unsigned* line)
74 struct find_info data;
76 data.symbol = b->symbol;
82 bfd_map_over_sections(b->handle, &lookup_section, &data);
99 output_print(ob,
"%s: Matching formats: ", procname);
101 output_print(ob,
" %s", *p++);
102 output_print(ob,
"\n");
105 static int init_bfd_ctx (
struct bfd_ctx* bc,
const char* procname,
struct output_buffer* ob)
109 char** matching =
nullptr;
111 bc->handle =
nullptr;
112 bc->symbol =
nullptr;
114 bfd* b = bfd_openr(procname, 0);
116 output_print(ob,
"Failed to open bfd from (%s)\n", procname);
120 if (bfd_check_format(b, bfd_archive)) {
121 output_print(ob,
"Cannot get addresses from archive (%s)\n", b->filename);
126 if (!bfd_check_format_matches(b, bfd_object, &matching)) {
127 const char* errmsg = bfd_errmsg(bfd_get_error());
128 output_print(ob,
"%s (%s)\n", errmsg, b->filename);
129 if (bfd_get_error() == bfd_error_file_ambiguously_recognized) {
137 if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
138 const char* errmsg = bfd_errmsg(bfd_get_error());
139 output_print(ob,
"Failed to get file flags from (%s) %s\n", b->filename, errmsg);
144 if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
145 if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
146 const char* errmsg = bfd_errmsg(bfd_get_error());
147 output_print(ob,
"Failed to read symbols from (%s): %s\n", b->filename, errmsg);
155 bc->symbol = (asymbol**)symbol_table;
160 static void close_bfd_ctx (
struct bfd_ctx* bc)
164 bfd_close(bc->handle);
168 struct bfd_ctx* get_bc (
struct output_buffer* ob,
struct bfd_set* set,
const char* procname)
173 if (
Q_streq(set->name, procname)) {
178 if (init_bfd_ctx(&bc, procname, ob)) {
181 set->next = (bfd_set*)calloc(1,
sizeof(*set));
182 set->bc = (bfd_ctx*)malloc(
sizeof(
struct bfd_ctx));
183 memcpy(set->bc, &bc,
sizeof(bc));
184 set->name = strdup(procname);
189 void release_set (
struct bfd_set* set)
192 struct bfd_set* temp = set->next;
194 close_bfd_ctx(set->bc);
void list_matching_formats(char **p)
GLsizei const GLvoid * data
void format(__printf__, 1, 2)))