34#ifndef bfd_get_section_flags
35# define bfd_get_section_flags(bfd, section) (bfd_section_flags(section))
38#ifndef bfd_get_section_vma
39# define bfd_get_section_vma(bfd, section) (bfd_section_vma(section))
42#ifndef bfd_get_section_size
43# define bfd_get_section_size(section) (bfd_section_size(section))
46void output_init (
struct output_buffer* ob,
char*
buf,
size_t sz)
54void output_print (
struct output_buffer* ob,
const char*
format, ...)
57 if (ob->sz == ob->ptr)
59 ob->buf[ob->ptr] =
'\0';
61 vsnprintf(ob->buf + ob->ptr, ob->sz - ob->ptr,
format, ap);
64 ob->ptr = strlen(ob->buf + ob->ptr) + ob->ptr;
67static void lookup_section (bfd* abfd, asection* sec,
void* opaque_data)
69 struct find_info*
data = (
struct find_info*)opaque_data;
74 if (!(bfd_get_section_flags(abfd, sec) & SEC_ALLOC))
77 const bfd_vma vma = bfd_get_section_vma(abfd, sec);
78 if (
data->counter < vma || vma + bfd_get_section_size(sec) <=
data->counter)
81 bfd_find_nearest_line(abfd, sec,
data->symbol,
data->counter - vma,
85void find (
struct bfd_ctx * b,
size_t offset,
const char** file,
const char** func,
unsigned* line)
87 struct find_info
data;
89 data.symbol = b->symbol;
95 bfd_map_over_sections(b->handle, &lookup_section, &
data);
112 output_print(ob,
"%s: Matching formats: ", procname);
114 output_print(ob,
" %s", *p++);
115 output_print(ob,
"\n");
118static int init_bfd_ctx (
struct bfd_ctx* bc,
const char* procname,
struct output_buffer* ob)
122 char** matching =
nullptr;
124 bc->handle =
nullptr;
125 bc->symbol =
nullptr;
127 bfd* b = bfd_openr(procname, 0);
129 output_print(ob,
"Failed to open bfd from (%s)\n", procname);
133 if (bfd_check_format(b, bfd_archive)) {
134 output_print(ob,
"Cannot get addresses from archive (%s)\n", b->filename);
139 if (!bfd_check_format_matches(b, bfd_object, &matching)) {
140 const char* errmsg = bfd_errmsg(bfd_get_error());
141 output_print(ob,
"%s (%s)\n", errmsg, b->filename);
142 if (bfd_get_error() == bfd_error_file_ambiguously_recognized) {
150 if ((bfd_get_file_flags(b) & HAS_SYMS) == 0) {
151 const char* errmsg = bfd_errmsg(bfd_get_error());
152 output_print(ob,
"Failed to get file flags from (%s) %s\n", b->filename, errmsg);
157 if (bfd_read_minisymbols(b, FALSE, &symbol_table, &dummy) == 0) {
158 if (bfd_read_minisymbols(b, TRUE, &symbol_table, &dummy) < 0) {
159 const char* errmsg = bfd_errmsg(bfd_get_error());
160 output_print(ob,
"Failed to read symbols from (%s): %s\n", b->filename, errmsg);
168 bc->symbol = (asymbol**)symbol_table;
173static void close_bfd_ctx (
struct bfd_ctx* bc)
177 bfd_close(bc->handle);
181struct bfd_ctx* get_bc (
struct output_buffer* ob,
struct bfd_set* set,
const char* procname)
186 if (
Q_streq(set->name, procname)) {
191 if (init_bfd_ctx(&bc, procname, ob)) {
194 set->next = (bfd_set*)calloc(1,
sizeof(*set));
195 set->bc = (bfd_ctx*)malloc(
sizeof(
struct bfd_ctx));
196 memcpy(set->bc, &bc,
sizeof(bc));
197 set->name = strdup(procname);
202void release_set (
struct bfd_set* set)
205 struct bfd_set* temp = set->next;
207 close_bfd_ctx(set->bc);
void list_matching_formats(char **p)
definitions common between client and server, but not game lib
void format(__printf__, 1, 2)))
QGL_EXTERN GLsizei const GLvoid * data