mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-10-16 12:24:19 +08:00
2002-06-21 Michal Ludvig <mludvig@suse.cz>
* dwarf2cfi.c (read_encoded_pointer): Don't handle pointer encoding anymore. (pointer_encoding, enum ptr_encoding): New. (execute_cfa_program): Take care about pointer encoding. (dwarf2_build_frame_info): Only call parse_frame_info for .debug_frame and .eh_frame. (parse_frame_info): New, derived from former dwarf2_build_frame_info. fixed augmentation handling, added relative addressing, ignore duplicate FDEs. Added comments.
This commit is contained in:
@ -1,3 +1,15 @@
|
|||||||
|
2002-06-21 Michal Ludvig <mludvig@suse.cz>
|
||||||
|
|
||||||
|
* dwarf2cfi.c (read_encoded_pointer): Don't handle pointer
|
||||||
|
encoding anymore.
|
||||||
|
(pointer_encoding, enum ptr_encoding): New.
|
||||||
|
(execute_cfa_program): Take care about pointer encoding.
|
||||||
|
(dwarf2_build_frame_info): Only call parse_frame_info for
|
||||||
|
.debug_frame and .eh_frame.
|
||||||
|
(parse_frame_info): New, derived from former dwarf2_build_frame_info.
|
||||||
|
fixed augmentation handling, added relative addressing,
|
||||||
|
ignore duplicate FDEs. Added comments.
|
||||||
|
|
||||||
2002-06-20 Elena Zannoni <ezannoni@redhat.com>
|
2002-06-20 Elena Zannoni <ezannoni@redhat.com>
|
||||||
|
|
||||||
* event-top.c (command_handler): Don't use space_at_cmd_start
|
* event-top.c (command_handler): Don't use space_at_cmd_start
|
||||||
|
304
gdb/dwarf2cfi.c
304
gdb/dwarf2cfi.c
@ -34,7 +34,7 @@
|
|||||||
Frame Descriptors. */
|
Frame Descriptors. */
|
||||||
struct cie_unit
|
struct cie_unit
|
||||||
{
|
{
|
||||||
/* Offset of this unit in dwarf_frame_buffer. */
|
/* Offset of this unit in .debug_frame or .eh_frame. */
|
||||||
ULONGEST offset;
|
ULONGEST offset;
|
||||||
|
|
||||||
/* A null-terminated string that identifies the augmentation to this CIE or
|
/* A null-terminated string that identifies the augmentation to this CIE or
|
||||||
@ -176,6 +176,14 @@ struct frame_state
|
|||||||
struct objfile *objfile;
|
struct objfile *objfile;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ptr_encoding {
|
||||||
|
PE_absptr = DW_EH_PE_absptr,
|
||||||
|
PE_pcrel = DW_EH_PE_pcrel,
|
||||||
|
PE_textrel = DW_EH_PE_textrel,
|
||||||
|
PE_datarel = DW_EH_PE_datarel,
|
||||||
|
PE_funcrel = DW_EH_PE_funcrel
|
||||||
|
};
|
||||||
|
|
||||||
#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
|
#define UNWIND_CONTEXT(fi) ((struct context *) (fi->context))
|
||||||
|
|
||||||
|
|
||||||
@ -188,8 +196,6 @@ extern file_ptr dwarf_frame_offset;
|
|||||||
extern unsigned int dwarf_frame_size;
|
extern unsigned int dwarf_frame_size;
|
||||||
extern file_ptr dwarf_eh_frame_offset;
|
extern file_ptr dwarf_eh_frame_offset;
|
||||||
extern unsigned int dwarf_eh_frame_size;
|
extern unsigned int dwarf_eh_frame_size;
|
||||||
|
|
||||||
static char *dwarf_frame_buffer;
|
|
||||||
|
|
||||||
|
|
||||||
extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
|
extern char *dwarf2_read_section (struct objfile *objfile, file_ptr offset,
|
||||||
@ -219,6 +225,7 @@ static LONGEST read_sleb128 (bfd * abfd, char **p);
|
|||||||
static CORE_ADDR read_pointer (bfd * abfd, char **p);
|
static CORE_ADDR read_pointer (bfd * abfd, char **p);
|
||||||
static CORE_ADDR read_encoded_pointer (bfd * abfd, char **p,
|
static CORE_ADDR read_encoded_pointer (bfd * abfd, char **p,
|
||||||
unsigned char encoding);
|
unsigned char encoding);
|
||||||
|
static enum ptr_encoding pointer_encoding (unsigned char encoding);
|
||||||
|
|
||||||
static LONGEST read_initial_length (bfd * abfd, char *buf, int *bytes_read);
|
static LONGEST read_initial_length (bfd * abfd, char *buf, int *bytes_read);
|
||||||
static ULONGEST read_length (bfd * abfd, char *buf, int *bytes_read,
|
static ULONGEST read_length (bfd * abfd, char *buf, int *bytes_read,
|
||||||
@ -494,6 +501,9 @@ read_pointer (bfd * abfd, char **p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This functions only reads appropriate amount of data from *p
|
||||||
|
* and returns the resulting value. Calling function must handle
|
||||||
|
* different encoding possibilities itself! */
|
||||||
static CORE_ADDR
|
static CORE_ADDR
|
||||||
read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
|
read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
|
||||||
{
|
{
|
||||||
@ -537,22 +547,34 @@ read_encoded_pointer (bfd * abfd, char **p, unsigned char encoding)
|
|||||||
"read_encoded_pointer: unknown pointer encoding");
|
"read_encoded_pointer: unknown pointer encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0)
|
return ret;
|
||||||
switch (encoding & 0xf0)
|
}
|
||||||
|
|
||||||
|
/* Variable 'encoding' carries 3 different flags:
|
||||||
|
* - encoding & 0x0f : size of the address (handled in read_encoded_pointer())
|
||||||
|
* - encoding & 0x70 : type (absolute, relative, ...)
|
||||||
|
* - encoding & 0x80 : indirect flag (DW_EH_PE_indirect == 0x80). */
|
||||||
|
enum ptr_encoding
|
||||||
|
pointer_encoding (unsigned char encoding)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (encoding & DW_EH_PE_indirect)
|
||||||
|
warning ("CFI: Unsupported pointer encoding: DW_EH_PE_indirect");
|
||||||
|
|
||||||
|
switch (encoding & 0x70)
|
||||||
{
|
{
|
||||||
case DW_EH_PE_absptr:
|
case DW_EH_PE_absptr:
|
||||||
break;
|
|
||||||
case DW_EH_PE_pcrel:
|
case DW_EH_PE_pcrel:
|
||||||
ret += (CORE_ADDR) * p;
|
|
||||||
break;
|
|
||||||
case DW_EH_PE_textrel:
|
case DW_EH_PE_textrel:
|
||||||
case DW_EH_PE_datarel:
|
case DW_EH_PE_datarel:
|
||||||
case DW_EH_PE_funcrel:
|
case DW_EH_PE_funcrel:
|
||||||
|
ret = encoding & 0x70;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
internal_error (__FILE__, __LINE__,
|
internal_error (__FILE__, __LINE__,
|
||||||
"read_encoded_pointer: unknown pointer encoding");
|
"CFI: unknown pointer encoding");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -627,6 +649,10 @@ execute_cfa_program (struct objfile *objfile, char *insn_ptr, char *insn_end,
|
|||||||
case DW_CFA_set_loc:
|
case DW_CFA_set_loc:
|
||||||
fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
|
fs->pc = read_encoded_pointer (objfile->obfd, &insn_ptr,
|
||||||
fs->addr_encoding);
|
fs->addr_encoding);
|
||||||
|
|
||||||
|
if (pointer_encoding (fs->addr_encoding) != PE_absptr)
|
||||||
|
warning ("CFI: DW_CFA_set_loc uses relative addressing");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DW_CFA_advance_loc1:
|
case DW_CFA_advance_loc1:
|
||||||
@ -1380,39 +1406,46 @@ compare_fde_unit (const void *a, const void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Build the cie_chunks and fde_chunks tables from informations
|
/* Build the cie_chunks and fde_chunks tables from informations
|
||||||
in .debug_frame section. */
|
found in .debug_frame and .eh_frame sections. */
|
||||||
void
|
/* We can handle both of these sections almost in the same way, however there
|
||||||
dwarf2_build_frame_info (struct objfile *objfile)
|
are some exceptions:
|
||||||
|
- CIE ID is -1 in debug_frame, but 0 in eh_frame
|
||||||
|
- eh_frame may contain some more information that are used only by gcc
|
||||||
|
(eg. personality pointer, LSDA pointer, ...). Most of them we can ignore.
|
||||||
|
- In debug_frame FDE's item cie_id contains offset of it's parent CIE.
|
||||||
|
In eh_frame FDE's item cie_id is a relative pointer to the parent CIE.
|
||||||
|
Anyway we don't need to bother with this, because we are smart enough
|
||||||
|
to keep the pointer to the parent CIE of oncomming FDEs in 'last_cie'.
|
||||||
|
- Although debug_frame items can contain Augmentation as well as
|
||||||
|
eh_frame ones, I have never seen them non-empty. Thus only in eh_frame
|
||||||
|
we can encounter for example non-absolute pointers (Aug. 'R').
|
||||||
|
-- mludvig */
|
||||||
|
static void
|
||||||
|
parse_frame_info (struct objfile *objfile, file_ptr frame_offset,
|
||||||
|
unsigned int frame_size, int eh_frame)
|
||||||
{
|
{
|
||||||
bfd *abfd = objfile->obfd;
|
bfd *abfd = objfile->obfd;
|
||||||
|
asection *curr_section_ptr;
|
||||||
char *start = NULL;
|
char *start = NULL;
|
||||||
char *end = NULL;
|
char *end = NULL;
|
||||||
int from_eh = 0;
|
char *frame_buffer = NULL;
|
||||||
|
char *curr_section_name, *aug_data;
|
||||||
|
struct cie_unit *last_cie = NULL;
|
||||||
|
int last_dup_fde = 0;
|
||||||
|
int aug_len, i;
|
||||||
|
CORE_ADDR curr_section_vma = 0;
|
||||||
|
|
||||||
unwind_tmp_obstack_init ();
|
unwind_tmp_obstack_init ();
|
||||||
|
|
||||||
dwarf_frame_buffer = 0;
|
frame_buffer = dwarf2_read_section (objfile, frame_offset, frame_size);
|
||||||
|
|
||||||
if (dwarf_frame_offset)
|
start = frame_buffer;
|
||||||
{
|
end = frame_buffer + frame_size;
|
||||||
dwarf_frame_buffer = dwarf2_read_section (objfile,
|
|
||||||
dwarf_frame_offset,
|
|
||||||
dwarf_frame_size);
|
|
||||||
|
|
||||||
start = dwarf_frame_buffer;
|
curr_section_name = eh_frame ? ".eh_frame" : ".debug_frame";
|
||||||
end = dwarf_frame_buffer + dwarf_frame_size;
|
curr_section_ptr = bfd_get_section_by_name (abfd, curr_section_name);
|
||||||
}
|
if (curr_section_ptr)
|
||||||
else if (dwarf_eh_frame_offset)
|
curr_section_vma = curr_section_ptr->vma;
|
||||||
{
|
|
||||||
dwarf_frame_buffer = dwarf2_read_section (objfile,
|
|
||||||
dwarf_eh_frame_offset,
|
|
||||||
dwarf_eh_frame_size);
|
|
||||||
|
|
||||||
start = dwarf_frame_buffer;
|
|
||||||
end = dwarf_frame_buffer + dwarf_eh_frame_size;
|
|
||||||
|
|
||||||
from_eh = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start)
|
if (start)
|
||||||
{
|
{
|
||||||
@ -1420,9 +1453,8 @@ dwarf2_build_frame_info (struct objfile *objfile)
|
|||||||
{
|
{
|
||||||
unsigned long length;
|
unsigned long length;
|
||||||
ULONGEST cie_id;
|
ULONGEST cie_id;
|
||||||
ULONGEST unit_offset = start - dwarf_frame_buffer;
|
ULONGEST unit_offset = start - frame_buffer;
|
||||||
int bytes_read;
|
int bytes_read, dwarf64, flag_pcrel;
|
||||||
int dwarf64;
|
|
||||||
char *block_end;
|
char *block_end;
|
||||||
|
|
||||||
length = read_initial_length (abfd, start, &bytes_read);
|
length = read_initial_length (abfd, start, &bytes_read);
|
||||||
@ -1430,10 +1462,16 @@ dwarf2_build_frame_info (struct objfile *objfile)
|
|||||||
dwarf64 = (bytes_read == 12);
|
dwarf64 = (bytes_read == 12);
|
||||||
block_end = start + length;
|
block_end = start + length;
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
{
|
||||||
|
start = block_end;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
cie_id = read_length (abfd, start, &bytes_read, dwarf64);
|
cie_id = read_length (abfd, start, &bytes_read, dwarf64);
|
||||||
start += bytes_read;
|
start += bytes_read;
|
||||||
|
|
||||||
if ((from_eh && cie_id == 0) || is_cie (cie_id, dwarf64))
|
if ((eh_frame && cie_id == 0) || is_cie (cie_id, dwarf64))
|
||||||
{
|
{
|
||||||
struct cie_unit *cie = cie_unit_alloc ();
|
struct cie_unit *cie = cie_unit_alloc ();
|
||||||
char *aug;
|
char *aug;
|
||||||
@ -1449,95 +1487,217 @@ dwarf2_build_frame_info (struct objfile *objfile)
|
|||||||
start++; /* version */
|
start++; /* version */
|
||||||
|
|
||||||
cie->augmentation = aug = start;
|
cie->augmentation = aug = start;
|
||||||
while (*start)
|
while (*start++); /* Skips last NULL as well */
|
||||||
start++;
|
|
||||||
start++; /* skip past NUL */
|
|
||||||
|
|
||||||
cie->code_align = read_uleb128 (abfd, &start);
|
cie->code_align = read_uleb128 (abfd, &start);
|
||||||
cie->data_align = read_sleb128 (abfd, &start);
|
cie->data_align = read_sleb128 (abfd, &start);
|
||||||
cie->ra = read_1u (abfd, &start);
|
cie->ra = read_1u (abfd, &start);
|
||||||
|
|
||||||
|
/* Augmentation:
|
||||||
|
z Indicates that a uleb128 is present to size the
|
||||||
|
augmentation section.
|
||||||
|
L Indicates the encoding (and thus presence) of
|
||||||
|
an LSDA pointer in the FDE augmentation.
|
||||||
|
R Indicates a non-default pointer encoding for
|
||||||
|
FDE code pointers.
|
||||||
|
P Indicates the presence of an encoding + language
|
||||||
|
personality routine in the CIE augmentation.
|
||||||
|
|
||||||
|
[This info comes from GCC's dwarf2out.c]
|
||||||
|
*/
|
||||||
if (*aug == 'z')
|
if (*aug == 'z')
|
||||||
{
|
{
|
||||||
int xtra = read_uleb128 (abfd, &start);
|
aug_len = read_uleb128 (abfd, &start);
|
||||||
start += xtra;
|
aug_data = start;
|
||||||
|
start += aug_len;
|
||||||
++aug;
|
++aug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cie->data = start;
|
||||||
|
cie->data_length = block_end - cie->data;
|
||||||
|
|
||||||
while (*aug != '\0')
|
while (*aug != '\0')
|
||||||
{
|
{
|
||||||
if (aug[0] == 'e' && aug[1] == 'h')
|
if (aug[0] == 'e' && aug[1] == 'h')
|
||||||
{
|
{
|
||||||
start += sizeof (void *);
|
aug_data += sizeof (void *);
|
||||||
aug += 2;
|
aug++;
|
||||||
}
|
}
|
||||||
else if (aug[0] == 'R')
|
else if (aug[0] == 'R')
|
||||||
{
|
cie->addr_encoding = *aug_data++;
|
||||||
cie->addr_encoding = *start++;
|
|
||||||
aug += 1;
|
|
||||||
}
|
|
||||||
else if (aug[0] == 'P')
|
else if (aug[0] == 'P')
|
||||||
{
|
{
|
||||||
CORE_ADDR ptr;
|
CORE_ADDR pers_addr;
|
||||||
ptr = read_encoded_pointer (abfd, &start,
|
int pers_addr_enc;
|
||||||
cie->addr_encoding);
|
|
||||||
aug += 1;
|
pers_addr_enc = *aug_data++;
|
||||||
|
/* We don't need pers_addr value and so we
|
||||||
|
don't care about it's encoding. */
|
||||||
|
pers_addr = read_encoded_pointer (abfd, &aug_data,
|
||||||
|
pers_addr_enc);
|
||||||
|
}
|
||||||
|
else if (aug[0] == 'L' && eh_frame)
|
||||||
|
{
|
||||||
|
int lsda_addr_enc;
|
||||||
|
|
||||||
|
/* Perhaps we should save this to CIE for later use?
|
||||||
|
Do we need it for something in GDB? */
|
||||||
|
lsda_addr_enc = *aug_data++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
warning ("%s(): unknown augmentation", __func__);
|
warning ("CFI warning: unknown augmentation \"%c\""
|
||||||
|
" in \"%s\" of\n"
|
||||||
|
"\t%s", aug[0], curr_section_name,
|
||||||
|
objfile->name);
|
||||||
|
aug++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cie->data = start;
|
last_cie = cie;
|
||||||
cie->data_length = block_end - start;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct fde_unit *fde;
|
struct fde_unit *fde;
|
||||||
struct cie_unit *cie;
|
struct cie_unit *cie;
|
||||||
|
int dup = 0;
|
||||||
|
CORE_ADDR init_loc;
|
||||||
|
|
||||||
fde_chunks_need_space ();
|
/* We assume that debug_frame is in order
|
||||||
fde = fde_unit_alloc ();
|
CIE,FDE,CIE,FDE,FDE,... and thus the CIE for this FDE
|
||||||
|
should be stored in last_cie pointer. If not, we'll
|
||||||
fde_chunks.array[fde_chunks.elems++] = fde;
|
try to find it by the older way. */
|
||||||
|
if (last_cie)
|
||||||
fde->initial_location = read_pointer (abfd, &start)
|
cie = last_cie;
|
||||||
+ ANOFFSET (objfile->section_offsets,
|
else
|
||||||
SECT_OFF_TEXT (objfile));
|
{
|
||||||
fde->address_range = read_pointer (abfd, &start);
|
warning ("CFI: last_cie == NULL. "
|
||||||
|
"Perhaps a malformed %s section in '%s'...?\n",
|
||||||
|
curr_section_name, objfile->name);
|
||||||
|
|
||||||
cie = cie_chunks;
|
cie = cie_chunks;
|
||||||
while (cie)
|
while (cie)
|
||||||
{
|
{
|
||||||
if (cie->objfile == objfile)
|
if (cie->objfile == objfile)
|
||||||
{
|
{
|
||||||
if (from_eh
|
if (eh_frame &&
|
||||||
&& (cie->offset ==
|
(cie->offset ==
|
||||||
(unit_offset + bytes_read - cie_id)))
|
(unit_offset + bytes_read - cie_id)))
|
||||||
break;
|
break;
|
||||||
if (!from_eh && (cie->offset == cie_id))
|
if (!eh_frame && (cie->offset == cie_id))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cie = cie->next;
|
cie = cie->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cie)
|
if (!cie)
|
||||||
error ("%s(): can't find CIE pointer", __func__);
|
error ("CFI: can't find CIE pointer");
|
||||||
|
}
|
||||||
|
|
||||||
|
init_loc = read_encoded_pointer (abfd, &start,
|
||||||
|
cie->addr_encoding);
|
||||||
|
|
||||||
|
switch (pointer_encoding (cie->addr_encoding))
|
||||||
|
{
|
||||||
|
case PE_absptr:
|
||||||
|
break;
|
||||||
|
case PE_pcrel:
|
||||||
|
/* start-frame_buffer gives offset from
|
||||||
|
the beginning of actual section. */
|
||||||
|
init_loc += curr_section_vma + start - frame_buffer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warning ("CFI: Unsupported pointer encoding\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For relocatable objects we must add an offset telling
|
||||||
|
where the section is actually mapped in the memory. */
|
||||||
|
init_loc += ANOFFSET (objfile->section_offsets,
|
||||||
|
SECT_OFF_TEXT (objfile));
|
||||||
|
|
||||||
|
/* If we have both .debug_frame and .eh_frame present in
|
||||||
|
a file, we must eliminate duplicate FDEs. For now we'll
|
||||||
|
run through all entries in fde_chunks and check it one
|
||||||
|
by one. Perhaps in the future we can implement a faster
|
||||||
|
searching algorithm. */
|
||||||
|
/* eh_frame==2 indicates, that this file has an already
|
||||||
|
parsed .debug_frame too. When eh_frame==1 it means, that no
|
||||||
|
.debug_frame is present and thus we don't need to check for
|
||||||
|
duplicities. eh_frame==0 means, that we parse .debug_frame
|
||||||
|
and don't need to care about duplicate FDEs, because
|
||||||
|
.debug_frame is parsed first. */
|
||||||
|
if (eh_frame == 2)
|
||||||
|
for (i = 0; eh_frame == 2 && i < fde_chunks.elems; i++)
|
||||||
|
{
|
||||||
|
/* We assume that FDEs in .debug_frame and .eh_frame
|
||||||
|
have the same order (if they are present, of course).
|
||||||
|
If we find a duplicate entry for one FDE and save
|
||||||
|
it's index to last_dup_fde it's very likely, that
|
||||||
|
we'll find an entry for the following FDE right after
|
||||||
|
the previous one. Thus in many cases we'll run this
|
||||||
|
loop only once. */
|
||||||
|
last_dup_fde = (last_dup_fde + i) % fde_chunks.elems;
|
||||||
|
if (fde_chunks.array[last_dup_fde]->initial_location
|
||||||
|
== init_loc)
|
||||||
|
{
|
||||||
|
dup = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate a new entry only if this FDE isn't a duplicate of
|
||||||
|
something we have already seen. */
|
||||||
|
if (!dup)
|
||||||
|
{
|
||||||
|
fde_chunks_need_space ();
|
||||||
|
fde = fde_unit_alloc ();
|
||||||
|
|
||||||
|
fde_chunks.array[fde_chunks.elems++] = fde;
|
||||||
|
|
||||||
|
fde->initial_location = init_loc;
|
||||||
|
fde->address_range = read_encoded_pointer (abfd, &start,
|
||||||
|
cie->
|
||||||
|
addr_encoding);
|
||||||
|
|
||||||
fde->cie_ptr = cie;
|
fde->cie_ptr = cie;
|
||||||
|
|
||||||
|
/* Here we intentionally ignore augmentation data
|
||||||
|
from FDE, because we don't need them. */
|
||||||
if (cie->augmentation[0] == 'z')
|
if (cie->augmentation[0] == 'z')
|
||||||
read_uleb128 (abfd, &start);
|
start += read_uleb128 (abfd, &start);
|
||||||
|
|
||||||
fde->data = start;
|
fde->data = start;
|
||||||
fde->data_length = block_end - start;
|
fde->data_length = block_end - start;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
start = block_end;
|
start = block_end;
|
||||||
}
|
}
|
||||||
qsort (fde_chunks.array, fde_chunks.elems,
|
qsort (fde_chunks.array, fde_chunks.elems,
|
||||||
sizeof (struct fde_unit *), compare_fde_unit);
|
sizeof (struct fde_unit *), compare_fde_unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We must parse both .debug_frame section and .eh_frame because
|
||||||
|
* not all frames must be present in both of these sections. */
|
||||||
|
void
|
||||||
|
dwarf2_build_frame_info (struct objfile *objfile)
|
||||||
|
{
|
||||||
|
int after_debug_frame = 0;
|
||||||
|
|
||||||
|
/* If we have .debug_frame then the parser is called with
|
||||||
|
eh_frame==0 for .debug_frame and eh_frame==2 for .eh_frame,
|
||||||
|
otherwise it's only called once for .eh_frame with argument
|
||||||
|
eh_frame==1. */
|
||||||
|
|
||||||
|
if (dwarf_frame_offset)
|
||||||
|
{
|
||||||
|
parse_frame_info (objfile, dwarf_frame_offset,
|
||||||
|
dwarf_frame_size, 0 /* = debug_frame */);
|
||||||
|
after_debug_frame = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dwarf_eh_frame_offset)
|
||||||
|
parse_frame_info (objfile, dwarf_eh_frame_offset, dwarf_eh_frame_size,
|
||||||
|
1 /* = eh_frame */ + after_debug_frame);
|
||||||
|
}
|
||||||
|
|
||||||
/* Return the frame address. */
|
/* Return the frame address. */
|
||||||
CORE_ADDR
|
CORE_ADDR
|
||||||
|
Reference in New Issue
Block a user