mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-28 22:40:24 +00:00
(process_dynamic_segment): Read syminfo section if available.
(process_syminfo): New function. Print syminfo information. (process_file): Call process_syminfo and free syminfo data at the end.
This commit is contained in:
parent
59587664ab
commit
fdf959ddcb
@ -73,6 +73,9 @@ unsigned int rela_size;
|
||||
char * dynamic_strings;
|
||||
char * string_table;
|
||||
Elf_Internal_Sym * dynamic_symbols;
|
||||
Elf_Internal_Syminfo * dynamic_syminfo;
|
||||
unsigned long int dynamic_syminfo_offset;
|
||||
unsigned int dynamic_syminfo_nent;
|
||||
char program_interpreter [64];
|
||||
int dynamic_info[DT_JMPREL + 1];
|
||||
int version_info[16];
|
||||
@ -1289,7 +1292,7 @@ process_program_headers (file)
|
||||
printf
|
||||
(_("\nProgram Header%s:\n"), elf_header.e_phnum > 1 ? "s" : "");
|
||||
printf
|
||||
(_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
|
||||
(_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
|
||||
}
|
||||
|
||||
loadaddr = -1;
|
||||
@ -1302,7 +1305,7 @@ process_program_headers (file)
|
||||
if (do_segments)
|
||||
{
|
||||
printf (" %-11.11s ", get_segment_type (segment->p_type));
|
||||
printf ("0x%5.5lx ", (unsigned long) segment->p_offset);
|
||||
printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
|
||||
printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
|
||||
printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
|
||||
printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
|
||||
@ -1521,6 +1524,7 @@ process_section_headers (file)
|
||||
and dynamic string table. */
|
||||
dynamic_symbols = NULL;
|
||||
dynamic_strings = NULL;
|
||||
dynamic_syminfo = NULL;
|
||||
for (i = 0, section = section_headers;
|
||||
i < elf_header.e_shnum;
|
||||
i ++, section ++)
|
||||
@ -1697,26 +1701,70 @@ static void
|
||||
dynamic_segment_mips_val (entry)
|
||||
Elf_Internal_Dyn *entry;
|
||||
{
|
||||
switch (entry->d_tag)
|
||||
{
|
||||
case DT_MIPS_LOCAL_GOTNO:
|
||||
case DT_MIPS_CONFLICTNO:
|
||||
case DT_MIPS_LIBLISTNO:
|
||||
case DT_MIPS_SYMTABNO:
|
||||
case DT_MIPS_UNREFEXTNO:
|
||||
case DT_MIPS_HIPAGENO:
|
||||
case DT_MIPS_DELTA_CLASS_NO:
|
||||
case DT_MIPS_DELTA_INSTANCE_NO:
|
||||
case DT_MIPS_DELTA_RELOC_NO:
|
||||
case DT_MIPS_DELTA_SYM_NO:
|
||||
case DT_MIPS_DELTA_CLASSSYM_NO:
|
||||
if (do_dynamic)
|
||||
if (do_dynamic)
|
||||
switch (entry->d_tag)
|
||||
{
|
||||
case DT_MIPS_FLAGS:
|
||||
if (entry->d_un.d_val == 0)
|
||||
printf ("NONE\n");
|
||||
else
|
||||
{
|
||||
static const char *opts[] =
|
||||
{
|
||||
"QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
|
||||
"NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
|
||||
"GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
|
||||
"REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
|
||||
"RLD_ORDER_SAFE"
|
||||
};
|
||||
unsigned int cnt;
|
||||
int first = 1;
|
||||
for (cnt = 0; cnt < sizeof (opts) / sizeof (opts[0]); ++cnt)
|
||||
if (entry->d_un.d_val & (1 << cnt))
|
||||
{
|
||||
printf ("%s%s", first ? "" : " ", opts[cnt]);
|
||||
first = 0;
|
||||
}
|
||||
puts ("");
|
||||
}
|
||||
break;
|
||||
|
||||
case DT_MIPS_IVERSION:
|
||||
if (dynamic_strings != NULL)
|
||||
printf ("Interface Version: %s\n",
|
||||
dynamic_strings + entry->d_un.d_val);
|
||||
else
|
||||
printf ("%#ld\n", (long) entry->d_un.d_ptr);
|
||||
break;
|
||||
|
||||
case DT_MIPS_TIME_STAMP:
|
||||
{
|
||||
char timebuf[20];
|
||||
time_t time = entry->d_un.d_val;
|
||||
strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
|
||||
printf ("Time Stamp: %s\n", timebuf);
|
||||
}
|
||||
break;
|
||||
|
||||
case DT_MIPS_RLD_VERSION:
|
||||
case DT_MIPS_LOCAL_GOTNO:
|
||||
case DT_MIPS_CONFLICTNO:
|
||||
case DT_MIPS_LIBLISTNO:
|
||||
case DT_MIPS_SYMTABNO:
|
||||
case DT_MIPS_UNREFEXTNO:
|
||||
case DT_MIPS_HIPAGENO:
|
||||
case DT_MIPS_DELTA_CLASS_NO:
|
||||
case DT_MIPS_DELTA_INSTANCE_NO:
|
||||
case DT_MIPS_DELTA_RELOC_NO:
|
||||
case DT_MIPS_DELTA_SYM_NO:
|
||||
case DT_MIPS_DELTA_CLASSSYM_NO:
|
||||
case DT_MIPS_COMPACT_SIZE:
|
||||
printf ("%#ld\n", (long) entry->d_un.d_ptr);
|
||||
break;
|
||||
default:
|
||||
if (do_dynamic)
|
||||
break;
|
||||
|
||||
default:
|
||||
printf ("%#lx\n", (long) entry->d_un.d_ptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse the dynamic segment */
|
||||
@ -1842,6 +1890,51 @@ process_dynamic_segment (file)
|
||||
}
|
||||
}
|
||||
|
||||
/* And find the syminfo section if available. */
|
||||
if (dynamic_syminfo == NULL)
|
||||
{
|
||||
unsigned int syminsz = 0;
|
||||
|
||||
for (i = 0, entry = dynamic_segment;
|
||||
i < dynamic_size;
|
||||
++i, ++ entry)
|
||||
{
|
||||
if (entry->d_tag == DT_SYMINENT)
|
||||
assert (sizeof (Elf_External_Syminfo) == entry->d_un.d_val);
|
||||
else if (entry->d_tag == DT_SYMINSZ)
|
||||
syminsz = entry->d_un.d_val;
|
||||
else if (entry->d_tag == DT_SYMINFO)
|
||||
dynamic_syminfo_offset = entry->d_un.d_val - loadaddr;
|
||||
}
|
||||
|
||||
if (dynamic_syminfo_offset != 0 && syminsz != 0)
|
||||
{
|
||||
Elf_External_Syminfo *extsyminfo;
|
||||
Elf_Internal_Syminfo *syminfo;
|
||||
|
||||
/* There is a syminfo section. Read the data. */
|
||||
GET_DATA_ALLOC (dynamic_syminfo_offset, syminsz, extsyminfo,
|
||||
Elf_External_Syminfo *, "symbol information");
|
||||
|
||||
dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
|
||||
if (dynamic_syminfo == NULL)
|
||||
{
|
||||
error (_("Out of memory\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
dynamic_syminfo_nent = syminsz / sizeof (Elf_External_Syminfo);
|
||||
for (i = 0, syminfo = dynamic_syminfo; i < dynamic_syminfo_nent;
|
||||
++i, ++syminfo)
|
||||
{
|
||||
syminfo->si_boundto = BYTE_GET (extsyminfo[i].si_boundto);
|
||||
syminfo->si_flags = BYTE_GET (extsyminfo[i].si_flags);
|
||||
}
|
||||
|
||||
free (extsyminfo);
|
||||
}
|
||||
}
|
||||
|
||||
if (do_dynamic && dynamic_addr)
|
||||
printf (_("\nDynamic segment at offset 0x%x contains %d entries:\n"),
|
||||
dynamic_addr, dynamic_size);
|
||||
@ -2950,6 +3043,61 @@ process_symbol_table (file)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
process_syminfo (file)
|
||||
FILE * file;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dynamic_syminfo == NULL
|
||||
|| !do_dynamic)
|
||||
/* No syminfo, this is ok. */
|
||||
return 1;
|
||||
|
||||
/* There better should be a dynamic symbol section. */
|
||||
if (dynamic_symbols == NULL || dynamic_strings == NULL)
|
||||
return 0;
|
||||
|
||||
if (dynamic_addr)
|
||||
printf (_("\nDynamic info segment at offset 0x%x contains %d entries:\n"),
|
||||
dynamic_syminfo_offset, dynamic_syminfo_nent);
|
||||
|
||||
printf (_(" Num: Name BoundTo Flags\n"));
|
||||
for (i = 0; i < dynamic_syminfo_nent; ++i)
|
||||
{
|
||||
unsigned short int flags = dynamic_syminfo[i].si_flags;
|
||||
|
||||
printf ("%4d: %-35s ", i,
|
||||
dynamic_strings + dynamic_symbols[i].st_name);
|
||||
|
||||
switch (dynamic_syminfo[i].si_boundto)
|
||||
{
|
||||
case SYMINFO_BT_SELF:
|
||||
fputs ("SELF ", stdout);
|
||||
break;
|
||||
case SYMINFO_BT_PARENT:
|
||||
fputs ("PARENT ", stdout);
|
||||
break;
|
||||
default:
|
||||
printf ("%-7d ", dynamic_syminfo[i].si_boundto);
|
||||
break;
|
||||
}
|
||||
|
||||
if (flags & SYMINFO_FLG_DIRECT)
|
||||
printf (" DIRECT");
|
||||
if (flags & SYMINFO_FLG_PASSTHRU)
|
||||
printf (" PASSTHRU");
|
||||
if (flags & SYMINFO_FLG_COPY)
|
||||
printf (" COPY");
|
||||
if (flags & SYMINFO_FLG_LAZYLOAD)
|
||||
printf (" LAZYLOAD");
|
||||
|
||||
puts ("");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
process_section_contents (file)
|
||||
FILE * file;
|
||||
@ -3116,14 +3264,14 @@ process_mips_specific (file)
|
||||
elib, Elf32_External_Lib *, "liblist");
|
||||
|
||||
printf ("\nSection '.liblist' contains %d entries:\n", liblistno);
|
||||
fputs (" Library Time Stamp Checksum Version Flags\n",
|
||||
fputs (" Library Time Stamp Checksum Version Flags\n",
|
||||
stdout);
|
||||
|
||||
for (cnt = 0; cnt < liblistno; ++cnt)
|
||||
{
|
||||
Elf32_Lib liblist;
|
||||
time_t time;
|
||||
char timebuf[17];
|
||||
char timebuf[20];
|
||||
|
||||
liblist.l_name = BYTE_GET (elib[cnt].l_name);
|
||||
time = BYTE_GET (elib[cnt].l_time_stamp);
|
||||
@ -3131,7 +3279,7 @@ process_mips_specific (file)
|
||||
liblist.l_version = BYTE_GET (elib[cnt].l_version);
|
||||
liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
|
||||
|
||||
strftime (timebuf, 17, "%Y-%m-%dT%H:%M", gmtime (&time));
|
||||
strftime (timebuf, 20, "%Y-%m-%dT%H:%M:%S", gmtime (&time));
|
||||
|
||||
printf ("%3d: %-20s %s %#10lx %-7ld %#lx\n", cnt,
|
||||
dynamic_strings + liblist.l_name, timebuf,
|
||||
@ -3438,6 +3586,8 @@ process_file (file_name)
|
||||
|
||||
process_symbol_table (file);
|
||||
|
||||
process_syminfo (file);
|
||||
|
||||
process_version_sections (file);
|
||||
|
||||
process_section_contents (file);
|
||||
@ -3469,6 +3619,12 @@ process_file (file_name)
|
||||
free (dynamic_symbols);
|
||||
dynamic_symbols = NULL;
|
||||
}
|
||||
|
||||
if (dynamic_syminfo)
|
||||
{
|
||||
free (dynamic_syminfo);
|
||||
dynamic_syminfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SUPPORT_DISASSEMBLY
|
||||
|
Loading…
Reference in New Issue
Block a user