Libdwarf updates from upstream, including bugfixes and proper mach-o universal binaru support. Huge thanks to the awesome maintainer.
This commit is contained in:
parent
d4bc913607
commit
1d0a6642cf
13
bundled/libdwarf/dwarf_abbrev.h
vendored
13
bundled/libdwarf/dwarf_abbrev.h
vendored
@ -27,6 +27,13 @@
|
||||
|
||||
*/
|
||||
|
||||
#ifndef DWARF_ABBREV_H
|
||||
#define DWARF_ABBREV_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* In a given CU, one of these is (eventually) set up
|
||||
for every abbreviation we need to find (and for all
|
||||
those earlier in the abbreviations for that CU).
|
||||
@ -67,3 +74,9 @@ int _dwarf_count_abbrev_entries(Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned *abbrev_implicit_const_count_out,
|
||||
Dwarf_Byte_Ptr *abbrev_ptr_out,
|
||||
Dwarf_Error *error);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* DWARF_ABBREV_H */
|
||||
|
||||
2
bundled/libdwarf/dwarf_alloc.c
vendored
2
bundled/libdwarf/dwarf_alloc.c
vendored
@ -1140,7 +1140,9 @@ _dwarf_free_all_of_one_debug(Dwarf_Debug dbg)
|
||||
/* de_alloc_tree might be NULL if
|
||||
global_de_alloc_tree_on is zero. */
|
||||
if (dbg->de_alloc_tree) {
|
||||
dbg->de_in_tdestroy = TRUE;
|
||||
dwarf_tdestroy(dbg->de_alloc_tree,tdestroy_free_node);
|
||||
dbg->de_in_tdestroy = FALSE;
|
||||
dbg->de_alloc_tree = 0;
|
||||
}
|
||||
_dwarf_free_static_errlist();
|
||||
|
||||
13
bundled/libdwarf/dwarf_alloc.h
vendored
13
bundled/libdwarf/dwarf_alloc.h
vendored
@ -26,6 +26,13 @@
|
||||
Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef DWARF_ALLOC_H
|
||||
#define DWARF_ALLOC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* #define DWARF_SIMPLE_MALLOC 1 */
|
||||
|
||||
char * _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned);
|
||||
@ -43,3 +50,9 @@ void _dwarf_error_destructor(void *);
|
||||
void _dwarf_add_to_static_err_list(Dwarf_Error err);
|
||||
void _dwarf_flush_static_error_list(void);
|
||||
void _dwarf_free_static_errlist(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* DWARF_ALLOC_H */
|
||||
|
||||
4
bundled/libdwarf/dwarf_errmsg_list.h
vendored
4
bundled/libdwarf/dwarf_errmsg_list.h
vendored
@ -682,6 +682,8 @@ static const char _dwarf_errmsgs[DW_DLE_LAST+1][DW_MAX_MSG_LEN] = {
|
||||
{"DW_DLE_LINE_COUNT_WRONG(500) A count in a line table is "
|
||||
"not valid. Corrupt data."},
|
||||
{"DW_DLE_ARITHMETIC_OVERFLOW(501) Arithmetic overflow. "
|
||||
" Corrupt Dwarf." }
|
||||
" Corrupt Dwarf." },
|
||||
{" DW_DLE_UNIVERSAL_BINARY_ERROR(502) Error reading Mach-O "
|
||||
"uninversal binary head. Corrupt Mach-O object." }
|
||||
};
|
||||
#endif /* DWARF_ERRMSG_LIST_H */
|
||||
|
||||
17
bundled/libdwarf/dwarf_frame.c
vendored
17
bundled/libdwarf/dwarf_frame.c
vendored
@ -2160,7 +2160,9 @@ dwarf_get_fde_for_die(Dwarf_Debug dbg,
|
||||
}
|
||||
/* DW_DLV_OK */
|
||||
|
||||
/* This is the only situation this is set. */
|
||||
/* This is the only situation this is set.
|
||||
and is really dangerous. as fde and cie
|
||||
are set for dealloc by dwarf_finish(). */
|
||||
new_fde->fd_fde_owns_cie = TRUE;
|
||||
/* Now read the cie corresponding to the fde,
|
||||
_dwarf_read_cie_fde_prefix checks
|
||||
@ -3416,14 +3418,21 @@ _dwarf_frame_destructor(void *frame)
|
||||
struct Dwarf_Frame_s *fp = frame;
|
||||
_dwarf_free_fde_table(fp);
|
||||
}
|
||||
|
||||
void
|
||||
_dwarf_fde_destructor(void *f)
|
||||
{
|
||||
struct Dwarf_Fde_s *fde = f;
|
||||
|
||||
if (fde->fd_fde_owns_cie) {
|
||||
/* This is just for dwarf_get_fde_for_die() */
|
||||
dwarf_dealloc(fde->fd_dbg,fde->fd_cie,DW_DLA_CIE);
|
||||
fde->fd_cie = 0;
|
||||
Dwarf_Debug dbg = fde->fd_dbg;
|
||||
|
||||
if (!dbg->de_in_tdestroy) {
|
||||
/* This is just for dwarf_get_fde_for_die() and
|
||||
must not be applied in alloc tree destruction. */
|
||||
dwarf_dealloc(fde->fd_dbg,fde->fd_cie,DW_DLA_CIE);
|
||||
fde->fd_cie = 0;
|
||||
}
|
||||
}
|
||||
if (fde->fd_have_fde_tab) {
|
||||
_dwarf_free_fde_table(&fde->fd_fde_table);
|
||||
|
||||
21
bundled/libdwarf/dwarf_frame2.c
vendored
21
bundled/libdwarf/dwarf_frame2.c
vendored
@ -975,10 +975,12 @@ _dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
|
||||
&gnu_personality_handler_addr,
|
||||
error);
|
||||
if (resz != DW_DLV_OK) {
|
||||
_dwarf_error_string(dbg, error,
|
||||
DW_DLE_FRAME_AUGMENTATION_UNKNOWN,
|
||||
"DW_DLE_FRAME_AUGMENTATION_UNKNOWN "
|
||||
" Reading gnu aug encodings failed");
|
||||
if (resz == DW_DLV_ERROR) {
|
||||
_dwarf_error_string(dbg, error,
|
||||
DW_DLE_FRAME_AUGMENTATION_UNKNOWN,
|
||||
"DW_DLE_FRAME_AUGMENTATION_UNKNOWN "
|
||||
" Reading gnu aug encodings failed");
|
||||
} /* DW_DLV_NO_ENTRY seems impossible. */
|
||||
return resz;
|
||||
}
|
||||
frame_ptr += adlen;
|
||||
@ -1119,7 +1121,7 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
|
||||
address_range in the FDE are read according to the CIE
|
||||
augmentation string instructions. */
|
||||
|
||||
{
|
||||
if (cieptr) {
|
||||
Dwarf_Small *fp_updated = 0;
|
||||
int res = _dwarf_read_encoded_ptr(dbg,
|
||||
section_pointer,
|
||||
@ -1150,6 +1152,15 @@ _dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
|
||||
return res;
|
||||
}
|
||||
frame_ptr = fp_updated;
|
||||
} else {
|
||||
_dwarf_error_string(dbg, error,
|
||||
DW_DLE_AUG_DATA_LENGTH_BAD,
|
||||
"DW_DLE_AUG_DATA_LENGTH_BAD: The "
|
||||
"gcc augmentation cannot be read, "
|
||||
"as no cie pointer is available "
|
||||
"to get critical data, "
|
||||
"Corrupt DWARF");
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
{
|
||||
Dwarf_Unsigned adlen = 0;
|
||||
|
||||
53
bundled/libdwarf/dwarf_generic_init.c
vendored
53
bundled/libdwarf/dwarf_generic_init.c
vendored
@ -125,6 +125,24 @@ set_global_paths_init(Dwarf_Debug dbg, Dwarf_Error* error)
|
||||
}
|
||||
|
||||
/* New in December 2018. */
|
||||
int dwarf_init_path_a(const char *path,
|
||||
char * true_path_out_buffer,
|
||||
unsigned true_path_bufferlen,
|
||||
unsigned groupnumber,
|
||||
unsigned universalnumber,
|
||||
Dwarf_Handler errhand,
|
||||
Dwarf_Ptr errarg,
|
||||
Dwarf_Debug * ret_dbg,
|
||||
Dwarf_Error * error)
|
||||
{
|
||||
return dwarf_init_path_dl_a(path,
|
||||
true_path_out_buffer,true_path_bufferlen,
|
||||
groupnumber,universalnumber,
|
||||
errhand,errarg,ret_dbg,
|
||||
0,0,0,
|
||||
error);
|
||||
}
|
||||
|
||||
int dwarf_init_path(const char *path,
|
||||
char * true_path_out_buffer,
|
||||
unsigned true_path_bufferlen,
|
||||
@ -134,9 +152,11 @@ int dwarf_init_path(const char *path,
|
||||
Dwarf_Debug * ret_dbg,
|
||||
Dwarf_Error * error)
|
||||
{
|
||||
return dwarf_init_path_dl(path,
|
||||
unsigned int universalnumber = 0;
|
||||
return dwarf_init_path_dl_a(path,
|
||||
true_path_out_buffer,true_path_bufferlen,
|
||||
groupnumber,errhand,errarg,ret_dbg,
|
||||
groupnumber,universalnumber,
|
||||
errhand,errarg,ret_dbg,
|
||||
0,0,0,
|
||||
error);
|
||||
}
|
||||
@ -192,6 +212,30 @@ dwarf_init_path_dl(const char *path,
|
||||
unsigned int dl_path_count,
|
||||
unsigned char * path_source,
|
||||
Dwarf_Error * error)
|
||||
{
|
||||
unsigned int universalnumber = 0;
|
||||
int res = 0;
|
||||
|
||||
res = dwarf_init_path_dl_a(path,
|
||||
true_path_out_buffer, true_path_bufferlen,
|
||||
groupnumber,universalnumber,
|
||||
errhand,errarg,ret_dbg, dl_path_array,
|
||||
dl_path_count,path_source,error);
|
||||
return res;
|
||||
}
|
||||
int
|
||||
dwarf_init_path_dl_a(const char *path,
|
||||
char * true_path_out_buffer,
|
||||
unsigned true_path_bufferlen,
|
||||
unsigned groupnumber,
|
||||
unsigned universalnumber,
|
||||
Dwarf_Handler errhand,
|
||||
Dwarf_Ptr errarg,
|
||||
Dwarf_Debug * ret_dbg,
|
||||
char ** dl_path_array,
|
||||
unsigned int dl_path_count,
|
||||
unsigned char * path_source,
|
||||
Dwarf_Error * error)
|
||||
{
|
||||
unsigned ftype = 0;
|
||||
unsigned endian = 0;
|
||||
@ -302,9 +346,11 @@ dwarf_init_path_dl(const char *path,
|
||||
*ret_dbg = dbg;
|
||||
return res;
|
||||
}
|
||||
case DW_FTYPE_APPLEUNIVERSAL:
|
||||
case DW_FTYPE_MACH_O: {
|
||||
res = _dwarf_macho_setup(fd,
|
||||
file_path,
|
||||
universalnumber,
|
||||
ftype,endian,offsetsize,filesize,
|
||||
groupnumber,errhand,errarg,&dbg,error);
|
||||
if (res != DW_DLV_OK) {
|
||||
@ -355,6 +401,7 @@ dwarf_init_b(int fd,
|
||||
unsigned ftype = 0;
|
||||
unsigned endian = 0;
|
||||
unsigned offsetsize = 0;
|
||||
unsigned universalnumber = 0;
|
||||
Dwarf_Unsigned filesize = 0;
|
||||
int res = 0;
|
||||
int errcode = 0;
|
||||
@ -387,10 +434,12 @@ dwarf_init_b(int fd,
|
||||
set_global_paths_init(*ret_dbg,error);
|
||||
return res2;
|
||||
}
|
||||
case DW_FTYPE_APPLEUNIVERSAL:
|
||||
case DW_FTYPE_MACH_O: {
|
||||
int resm = 0;
|
||||
|
||||
resm = _dwarf_macho_setup(fd,"",
|
||||
universalnumber,
|
||||
ftype,endian,offsetsize,filesize,
|
||||
group_number,errhand,errarg,ret_dbg,error);
|
||||
if (resm != DW_DLV_OK) {
|
||||
|
||||
29
bundled/libdwarf/dwarf_macho_loader.h
vendored
29
bundled/libdwarf/dwarf_macho_loader.h
vendored
@ -76,6 +76,35 @@ extern "C" {
|
||||
#define TYP(n,l) char (n)[(l)]
|
||||
#endif /* TYP */
|
||||
|
||||
/* This is Apple internal naming for Universal Binaries
|
||||
and is not 'Inclusive Terminology" !! */
|
||||
#define FAT_MAGIC 0xcafebabe
|
||||
#define FAT_CIGAM 0xbebafeca
|
||||
#define FAT_MAGIC_64 0xcafebabf
|
||||
#define FAT_CIGAM_64 0xbfbafeca
|
||||
|
||||
struct fat_header {
|
||||
TYP(magic,4); /* FAT_MAGIC or FAT_MAGIC_64 */
|
||||
TYP(nfat_arch,4); /* number of structs that follow */
|
||||
};
|
||||
|
||||
struct fat_arch {
|
||||
TYP(cputype ,4); /* cpu specifier (int) */
|
||||
TYP(cpusubtype,4); /* machine specifier (int) */
|
||||
TYP(offset,4); /* file offset to this object file */
|
||||
TYP(size,4); /* size of this object file */
|
||||
TYP(align,4); /* alignment as a power of 2 */
|
||||
};
|
||||
|
||||
struct fat_arch_64 {
|
||||
TYP(cputype,4); /* cpu specifier (int) */
|
||||
TYP(cpusubtype,4); /* machine specifier (int) */
|
||||
TYP(offset,8); /* file offset to this object file */
|
||||
TYP(size,8); /* size of this object file */
|
||||
TYP(align,4); /* alignment as a power of 2 */
|
||||
TYP(reserved,4); /* reserved */
|
||||
};
|
||||
|
||||
/*
|
||||
* The 32-bit mach header appears at the very
|
||||
* beginning of the object file for
|
||||
|
||||
483
bundled/libdwarf/dwarf_machoread.c
vendored
483
bundled/libdwarf/dwarf_machoread.c
vendored
@ -75,6 +75,8 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <unistd.h> /* close() */
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <stdio.h> /* debugging printf */
|
||||
|
||||
#include "dwarf.h"
|
||||
#include "libdwarf.h"
|
||||
#include "libdwarf_private.h"
|
||||
@ -85,10 +87,26 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "dwarf_reading.h"
|
||||
#include "dwarf_memcpy_swap.h"
|
||||
#include "dwarf_object_read_common.h"
|
||||
#include "dwarf_universal.h"
|
||||
#include "dwarf_machoread.h"
|
||||
#include "dwarf_object_detector.h"
|
||||
#include "dwarf_macho_loader.h"
|
||||
|
||||
#if 0
|
||||
static void
|
||||
dump_bytes(const char *msg,Dwarf_Small * start, long len)
|
||||
{
|
||||
Dwarf_Small *end = start + len;
|
||||
Dwarf_Small *cur = start;
|
||||
printf("%s (0x%lx) ",msg,(unsigned long)start);
|
||||
for (; cur < end; cur++) {
|
||||
printf("%02x", *cur);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif /*0*/
|
||||
|
||||
|
||||
/* MACH-O and dwarf section names */
|
||||
static struct macho_sect_names_s {
|
||||
char const *ms_moname;
|
||||
@ -111,12 +129,21 @@ static struct macho_sect_names_s {
|
||||
};
|
||||
|
||||
static int
|
||||
_dwarf_macho_object_access_init(
|
||||
_dwarf_object_detector_universal_head_fd(
|
||||
int fd,
|
||||
Dwarf_Unsigned dw_filesize,
|
||||
unsigned int *dw_contentcount,
|
||||
Dwarf_Universal_Head * dw_head,
|
||||
int *errcode);
|
||||
|
||||
static int _dwarf_macho_object_access_init(
|
||||
int fd,
|
||||
unsigned uninumber,
|
||||
unsigned ftype,
|
||||
unsigned endian,
|
||||
unsigned offsetsize,
|
||||
size_t filesize,
|
||||
unsigned * universalbinary_count,
|
||||
Dwarf_Unsigned filesize,
|
||||
Dwarf_Obj_Access_Interface_a **binary_interface,
|
||||
int *localerrnum);
|
||||
|
||||
@ -192,6 +219,7 @@ macho_load_section (void *obj, Dwarf_Unsigned section_index,
|
||||
if (0 < section_index &&
|
||||
section_index < macho->mo_dwarf_sectioncount) {
|
||||
int res = 0;
|
||||
Dwarf_Unsigned inner = macho->mo_inner_offset;
|
||||
|
||||
struct generic_macho_section *sp =
|
||||
macho->mo_dwarf_sections + section_index;
|
||||
@ -214,8 +242,9 @@ macho_load_section (void *obj, Dwarf_Unsigned section_index,
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(macho->mo_fd,
|
||||
sp->loaded_data, (off_t)sp->offset,
|
||||
(size_t)sp->size, (off_t)macho->mo_filesize, error);
|
||||
sp->loaded_data, (off_t)(inner+sp->offset),
|
||||
(size_t)sp->size,
|
||||
(off_t)(inner+macho->mo_filesize), error);
|
||||
if (res != DW_DLV_OK) {
|
||||
free(sp->loaded_data);
|
||||
sp->loaded_data = 0;
|
||||
@ -276,13 +305,14 @@ load_macho_header32(dwarf_macho_object_access_internals_t *mfp,
|
||||
{
|
||||
struct mach_header mh32;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
if (sizeof(mh32) > mfp->mo_filesize) {
|
||||
*errcode = DW_DLE_FILE_TOO_SMALL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(mfp->mo_fd, &mh32, 0, sizeof(mh32),
|
||||
(off_t)mfp->mo_filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &mh32, inner, sizeof(mh32),
|
||||
(off_t)(inner+mfp->mo_filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -316,13 +346,14 @@ load_macho_header64(dwarf_macho_object_access_internals_t *mfp,
|
||||
{
|
||||
struct mach_header_64 mh64;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
if (sizeof(mh64) > mfp->mo_filesize) {
|
||||
*errcode = DW_DLE_FILE_TOO_SMALL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(mfp->mo_fd, &mh64, 0, sizeof(mh64),
|
||||
(off_t)mfp->mo_filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &mh64, inner, sizeof(mh64),
|
||||
(off_t)(inner+mfp->mo_filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -378,15 +409,16 @@ load_segment_command_content32(
|
||||
Dwarf_Unsigned filesize = mfp->mo_filesize;
|
||||
Dwarf_Unsigned segoffset = mmp->offset_this_command;
|
||||
Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc);
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
if (mmp->offset_this_command > filesize ||
|
||||
if (segoffset > filesize ||
|
||||
mmp->cmdsize > filesize ||
|
||||
(mmp->cmdsize + mmp->offset_this_command) > filesize ) {
|
||||
(mmp->cmdsize + segoffset) > filesize ) {
|
||||
*errcode = DW_DLE_MACH_O_SEGOFFSET_BAD;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command,
|
||||
sizeof(sc), (off_t)filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &sc, (off_t)(inner+segoffset),
|
||||
sizeof(sc), (off_t)(inner+filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -432,6 +464,8 @@ load_segment_command_content32(
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
void fuck() {}
|
||||
|
||||
static int
|
||||
load_segment_command_content64(
|
||||
dwarf_macho_object_access_internals_t *mfp,
|
||||
@ -444,15 +478,17 @@ load_segment_command_content64(
|
||||
Dwarf_Unsigned filesize = mfp->mo_filesize;
|
||||
Dwarf_Unsigned segoffset = mmp->offset_this_command;
|
||||
Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc);
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
if (segoffset > filesize ||
|
||||
mmp->cmdsize > filesize ||
|
||||
(mmp->cmdsize + segoffset) > filesize ) {
|
||||
*errcode = DW_DLE_MACHO_CORRUPT_COMMAND;
|
||||
fuck();
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(mfp->mo_fd,&sc,segoffset,
|
||||
sizeof(sc), (off_t)filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd,&sc,inner+segoffset,
|
||||
sizeof(sc), (off_t)(inner+filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -468,11 +504,13 @@ load_segment_command_content64(
|
||||
msp->filesize > filesize) {
|
||||
/* corrupt */
|
||||
*errcode = DW_DLE_MACHO_CORRUPT_COMMAND;
|
||||
fuck();
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if ((msp->fileoff+msp->filesize ) > filesize) {
|
||||
/* corrupt */
|
||||
*errcode = DW_DLE_MACHO_CORRUPT_COMMAND;
|
||||
fuck();
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot);
|
||||
@ -489,9 +527,9 @@ load_segment_command_content64(
|
||||
(unsigned long)mfp->mo_filesize);
|
||||
#endif
|
||||
*errcode = DW_DLE_MACHO_CORRUPT_COMMAND;
|
||||
fuck();
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
ASNAR(mfp->mo_copy_word,msp->flags,sc.flags);
|
||||
msp->macho_command_index = mmpindex;
|
||||
msp->sectionsoffset = afterseghdr;
|
||||
@ -580,6 +618,7 @@ _dwarf_macho_load_dwarf_section_details32(
|
||||
struct section mosec;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned endoffset = 0;
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
endoffset = curoff + sizeof(mosec);
|
||||
if (curoff >= mfp->mo_filesize ||
|
||||
@ -596,8 +635,8 @@ _dwarf_macho_load_dwarf_section_details32(
|
||||
*errcode = DW_DLE_MACHO_CORRUPT_SECTIONDETAILS;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec),
|
||||
(off_t)mfp->mo_filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &mosec, (off_t)(inner+curoff), sizeof(mosec),
|
||||
(off_t)(inner+mfp->mo_filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -667,8 +706,8 @@ _dwarf_macho_load_dwarf_section_details64(
|
||||
for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) {
|
||||
int res = 0;
|
||||
struct section_64 mosec;
|
||||
|
||||
Dwarf_Unsigned endoffset = 0;
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
endoffset = curoff + sizeof(mosec);
|
||||
if (curoff >= mfp->mo_filesize ||
|
||||
@ -686,8 +725,9 @@ _dwarf_macho_load_dwarf_section_details64(
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec),
|
||||
(off_t)mfp->mo_filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &mosec,
|
||||
(off_t)(inner+curoff), sizeof(mosec),
|
||||
(off_t)(inner+mfp->mo_filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -773,6 +813,7 @@ _dwarf_load_macho_commands(
|
||||
struct generic_macho_command *mcp = 0;
|
||||
unsigned segment_command_count = 0;
|
||||
int res = 0;
|
||||
Dwarf_Unsigned inner = mfp->mo_inner_offset;
|
||||
|
||||
if (mfp->mo_command_count >= mfp->mo_filesize) {
|
||||
/* corrupt object. */
|
||||
@ -795,8 +836,9 @@ _dwarf_load_macho_commands(
|
||||
}
|
||||
mcp = mfp->mo_commands;
|
||||
for ( ; cmdi < mfp->mo_header.ncmds; ++cmdi,++mcp ) {
|
||||
res = RRMOA(mfp->mo_fd, &mc, (off_t)curoff, sizeof(mc),
|
||||
(off_t)mfp->mo_filesize, errcode);
|
||||
res = RRMOA(mfp->mo_fd, &mc,
|
||||
(off_t)(inner+curoff), sizeof(mc),
|
||||
(off_t)(inner+mfp->mo_filesize), errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
@ -825,10 +867,11 @@ _dwarf_load_macho_commands(
|
||||
int
|
||||
_dwarf_macho_setup(int fd,
|
||||
char *true_path,
|
||||
unsigned universalnumber,
|
||||
unsigned ftype,
|
||||
unsigned endian,
|
||||
unsigned offsetsize,
|
||||
size_t filesize,
|
||||
Dwarf_Unsigned filesize,
|
||||
unsigned groupnumber,
|
||||
Dwarf_Handler errhand,
|
||||
Dwarf_Ptr errarg,
|
||||
@ -838,10 +881,14 @@ _dwarf_macho_setup(int fd,
|
||||
dwarf_macho_object_access_internals_t *intfc = 0;
|
||||
int res = DW_DLV_OK;
|
||||
int localerrnum = 0;
|
||||
unsigned universalbinary_count = 0;
|
||||
|
||||
res = _dwarf_macho_object_access_init(
|
||||
fd,
|
||||
ftype,endian,offsetsize,filesize,
|
||||
universalnumber,
|
||||
ftype,endian,offsetsize,
|
||||
&universalbinary_count,
|
||||
filesize,
|
||||
&binary_interface,
|
||||
&localerrnum);
|
||||
if (res != DW_DLV_OK) {
|
||||
@ -861,6 +908,8 @@ _dwarf_macho_setup(int fd,
|
||||
}
|
||||
intfc = binary_interface->ai_object;
|
||||
intfc->mo_path = strdup(true_path);
|
||||
(*dbg)->de_universalbinary_index = universalnumber;
|
||||
(*dbg)->de_universalbinary_count = universalbinary_count;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -877,15 +926,86 @@ static Dwarf_Obj_Access_Methods_a const macho_methods = {
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Reads universal binary headers, gets to
|
||||
the chosen inner binary, and returns the
|
||||
values from the inner binary.
|
||||
The filesize being that of the inner binary,
|
||||
and the fileoffset being the offset of the inner
|
||||
binary (so by definition > 0);
|
||||
*/
|
||||
|
||||
static int
|
||||
_dwarf_macho_inner_object_fd(int fd,
|
||||
unsigned int uninumber,
|
||||
Dwarf_Unsigned outer_filesize,
|
||||
unsigned int *ftype,
|
||||
unsigned int *unibinarycount,
|
||||
unsigned int *endian,
|
||||
unsigned int *offsetsize,
|
||||
Dwarf_Unsigned *fileoffset,
|
||||
Dwarf_Unsigned *filesize,
|
||||
int *errcode)
|
||||
{
|
||||
int res = 0;
|
||||
Dwarf_Universal_Head head = 0;
|
||||
Dwarf_Unsigned innerbase = 0;
|
||||
Dwarf_Unsigned innersize = 0;
|
||||
|
||||
res = _dwarf_object_detector_universal_head_fd(
|
||||
fd, outer_filesize, unibinarycount,
|
||||
&head, errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
return res;
|
||||
}
|
||||
if (uninumber >= *unibinarycount) {
|
||||
*errcode = DW_DLE_UNIVERSAL_BINARY_ERROR;
|
||||
_dwarf_dealloc_universal_head(head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
/* Now find the precise details of uninumber
|
||||
instance we want */
|
||||
|
||||
innerbase = head->au_arches[uninumber].au_offset;
|
||||
innersize = head->au_arches[uninumber].au_size;
|
||||
if (innersize >= outer_filesize ||
|
||||
innerbase >= outer_filesize) {
|
||||
*errcode = DW_DLE_UNIVERSAL_BINARY_ERROR;
|
||||
_dwarf_dealloc_universal_head(head);
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
/* Now access inner to return its specs */
|
||||
{
|
||||
/* But ignore the size this returns!
|
||||
we determined that above. the following call
|
||||
does not get the inner size, we got that
|
||||
just above here! */
|
||||
Dwarf_Unsigned fake_size = 0;
|
||||
|
||||
res = _dwarf_object_detector_fd_a(fd,
|
||||
ftype,endian,offsetsize,innerbase,&fake_size,
|
||||
errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
_dwarf_dealloc_universal_head(head);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
*fileoffset = innerbase;
|
||||
*filesize = innersize;
|
||||
_dwarf_dealloc_universal_head(head);
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
/* On any error this frees internals argument. */
|
||||
static int
|
||||
_dwarf_macho_object_access_internals_init(
|
||||
dwarf_macho_object_access_internals_t * internals,
|
||||
int fd,
|
||||
unsigned uninumber,
|
||||
unsigned ftype,
|
||||
unsigned endian,
|
||||
unsigned offsetsize,
|
||||
size_t filesize,
|
||||
unsigned *unibinarycount,
|
||||
Dwarf_Unsigned filesize,
|
||||
int *errcode)
|
||||
{
|
||||
dwarf_macho_object_access_internals_t * intfc = internals;
|
||||
@ -893,6 +1013,12 @@ _dwarf_macho_object_access_internals_init(
|
||||
struct generic_macho_section *sp = 0;
|
||||
struct Dwarf_Obj_Access_Interface_a_s *localdoas;
|
||||
int res = 0;
|
||||
unsigned int ftypei = ftype;
|
||||
unsigned int endiani = endian;
|
||||
unsigned int offsetsizei = offsetsize;
|
||||
Dwarf_Unsigned filesizei = filesize;
|
||||
Dwarf_Unsigned fileoffseti = 0;
|
||||
unsigned int unibinarycounti = 0;
|
||||
|
||||
/* Must malloc as _dwarf_destruct_macho_access()
|
||||
forces that due to other uses. */
|
||||
@ -903,15 +1029,34 @@ _dwarf_macho_object_access_internals_init(
|
||||
*errcode = DW_DLE_ALLOC_FAIL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_a_s));
|
||||
if (ftype == DW_FTYPE_APPLEUNIVERSAL) {
|
||||
res = _dwarf_macho_inner_object_fd(fd,
|
||||
uninumber,
|
||||
filesize,
|
||||
&ftypei,&unibinarycounti,&endiani,
|
||||
&offsetsizei,&fileoffseti,&filesizei,errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
if (res == DW_DLV_ERROR) {
|
||||
*errcode = DW_DLE_UNIVERSAL_BINARY_ERROR;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
*unibinarycount = unibinarycounti;
|
||||
endian = endiani;
|
||||
}
|
||||
|
||||
memset(localdoas,0,
|
||||
sizeof(struct Dwarf_Obj_Access_Interface_a_s));
|
||||
intfc->mo_ident[0] = 'M';
|
||||
intfc->mo_ident[1] = '1';
|
||||
intfc->mo_fd = fd;
|
||||
intfc->mo_is_64bit = ((offsetsize==64)?TRUE:FALSE);
|
||||
intfc->mo_offsetsize = offsetsize;
|
||||
intfc->mo_pointersize = offsetsize;
|
||||
intfc->mo_filesize = filesize;
|
||||
intfc->mo_ftype = ftype;
|
||||
intfc->mo_offsetsize = offsetsizei;
|
||||
intfc->mo_pointersize = offsetsizei;
|
||||
intfc->mo_inner_offset = fileoffseti;
|
||||
intfc->mo_filesize = filesizei;
|
||||
intfc->mo_ftype = ftypei;
|
||||
intfc->mo_uninumber = uninumber;
|
||||
intfc->mo_universal_count = unibinarycounti;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (endian == DW_END_little ) {
|
||||
@ -974,10 +1119,12 @@ _dwarf_macho_object_access_internals_init(
|
||||
static int
|
||||
_dwarf_macho_object_access_init(
|
||||
int fd,
|
||||
unsigned uninumber,
|
||||
unsigned ftype,
|
||||
unsigned endian,
|
||||
unsigned offsetsize,
|
||||
size_t filesize,
|
||||
unsigned * universalbinary_count,
|
||||
Dwarf_Unsigned filesize,
|
||||
Dwarf_Obj_Access_Interface_a **binary_interface,
|
||||
int *localerrnum)
|
||||
{
|
||||
@ -986,7 +1133,8 @@ _dwarf_macho_object_access_init(
|
||||
dwarf_macho_object_access_internals_t *internals = 0;
|
||||
Dwarf_Obj_Access_Interface_a *intfc = 0;
|
||||
|
||||
internals = malloc(sizeof(dwarf_macho_object_access_internals_t));
|
||||
internals = malloc(
|
||||
sizeof(dwarf_macho_object_access_internals_t));
|
||||
if (!internals) {
|
||||
*localerrnum = DW_DLE_ALLOC_FAIL;
|
||||
/* Impossible case, we hope. Give up. */
|
||||
@ -995,7 +1143,10 @@ _dwarf_macho_object_access_init(
|
||||
memset(internals,0,sizeof(*internals));
|
||||
res = _dwarf_macho_object_access_internals_init(internals,
|
||||
fd,
|
||||
ftype, endian, offsetsize, filesize,
|
||||
uninumber,
|
||||
ftype, endian, offsetsize,
|
||||
universalbinary_count,
|
||||
filesize,
|
||||
localerrnum);
|
||||
if (res != DW_DLV_OK){
|
||||
/* *err is already set and the call freed internals. */
|
||||
@ -1015,3 +1166,267 @@ _dwarf_macho_object_access_init(
|
||||
*binary_interface = intfc;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
magic_copy(unsigned char *d, unsigned len)
|
||||
{
|
||||
unsigned i = 0;
|
||||
unsigned long v = 0;
|
||||
|
||||
v = d[0];
|
||||
for (i = 1 ; i < len; ++i) {
|
||||
v <<= 8;
|
||||
v |= d[i];
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
static int
|
||||
fill_in_uni_arch_32(
|
||||
struct fat_arch * fa,
|
||||
struct Dwarf_Universal_Head_s *duhd,
|
||||
void (*word_swap) (void *, const void *, size_t))
|
||||
{
|
||||
Dwarf_Unsigned i = 0;
|
||||
struct Dwarf_Universal_Arch_s * dua = 0;
|
||||
|
||||
dua = duhd->au_arches;
|
||||
for ( ; i < duhd->au_count; ++i,++fa,++dua) {
|
||||
ASNAR(word_swap,dua->au_cputype,fa->cputype);
|
||||
ASNAR(word_swap,dua->au_cpusubtype,fa->cpusubtype);
|
||||
ASNAR(word_swap,dua->au_offset,fa->offset);
|
||||
ASNAR(word_swap,dua->au_size,fa->size);
|
||||
ASNAR(word_swap,dua->au_align,fa->align);
|
||||
dua->au_reserved = 0;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
fill_in_uni_arch_64(
|
||||
struct fat_arch_64 * fa,
|
||||
struct Dwarf_Universal_Head_s *duhd,
|
||||
void (*word_swap) (void *, const void *, size_t))
|
||||
{
|
||||
Dwarf_Unsigned i = 0;
|
||||
struct Dwarf_Universal_Arch_s * dua = 0;
|
||||
|
||||
dua = duhd->au_arches;
|
||||
for ( ; i < duhd->au_count; ++i,++fa,++dua) {
|
||||
ASNAR(word_swap,dua->au_cputype,fa->cputype);
|
||||
ASNAR(word_swap,dua->au_cpusubtype,fa->cpusubtype);
|
||||
ASNAR(word_swap,dua->au_offset,fa->offset);
|
||||
ASNAR(word_swap,dua->au_size,fa->size);
|
||||
ASNAR(word_swap,dua->au_align,fa->align);
|
||||
ASNAR(word_swap,dua->au_align,fa->align);
|
||||
ASNAR(word_swap,dua->au_reserved,fa->reserved);
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
static const struct Dwarf_Universal_Head_s duhzero;
|
||||
static const struct fat_header fhzero;
|
||||
static int
|
||||
_dwarf_object_detector_universal_head_fd(
|
||||
int fd,
|
||||
Dwarf_Unsigned dw_filesize,
|
||||
unsigned int *dw_contentcount,
|
||||
Dwarf_Universal_Head * dw_head,
|
||||
int *errcode)
|
||||
{
|
||||
struct Dwarf_Universal_Head_s duhd;
|
||||
struct Dwarf_Universal_Head_s *duhdp = 0;
|
||||
struct fat_header fh;
|
||||
int res = 0;
|
||||
void (*word_swap) (void *, const void *, size_t);
|
||||
int locendian = 0;
|
||||
int locoffsetsize = 0;
|
||||
|
||||
duhd = duhzero;
|
||||
fh = fhzero;
|
||||
/* A universal head is always at offset zero. */
|
||||
res = RRMOA(fd,&fh,0,sizeof(fh), dw_filesize,errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
printf("Reading struct for universal binary "
|
||||
"header failed\n");
|
||||
return res;
|
||||
}
|
||||
duhd.au_magic = magic_copy((unsigned char *)&fh.magic[0],4);
|
||||
if (duhd.au_magic == FAT_MAGIC) {
|
||||
locendian = DW_END_big;
|
||||
locoffsetsize = 32;
|
||||
} else if (duhd.au_magic == FAT_CIGAM) {
|
||||
locendian = DW_END_little;
|
||||
locoffsetsize = 32;
|
||||
}else if (duhd.au_magic == FAT_MAGIC_64) {
|
||||
locendian = DW_END_big;
|
||||
locoffsetsize = 64;
|
||||
} else if (duhd.au_magic == FAT_CIGAM_64) {
|
||||
locendian = DW_END_little;
|
||||
locoffsetsize = 64;
|
||||
} else {
|
||||
printf("Reading magic number universal compare failed " "Inconsistent\n");
|
||||
*errcode = DW_DLE_FILE_WRONG_TYPE;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (locendian == DW_END_little) {
|
||||
word_swap = _dwarf_memcpy_swap_bytes;
|
||||
} else {
|
||||
word_swap = _dwarf_memcpy_noswap_bytes;
|
||||
}
|
||||
#else /* LITTLE ENDIAN */
|
||||
if (locendian == DW_END_little) {
|
||||
word_swap = _dwarf_memcpy_noswap_bytes;
|
||||
} else {
|
||||
word_swap = _dwarf_memcpy_swap_bytes;
|
||||
}
|
||||
#endif /* LITTLE- BIG-ENDIAN */
|
||||
|
||||
ASNAR(word_swap,duhd.au_count,fh.nfat_arch);
|
||||
/* The limit is a first-cut safe heuristic. */
|
||||
if (duhd.au_count >= (dw_filesize/2) ) {
|
||||
*errcode = DW_DLE_UNIVERSAL_BINARY_ERROR ;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
duhd.au_arches = (struct Dwarf_Universal_Arch_s*)
|
||||
calloc(duhd.au_count, sizeof(struct Dwarf_Universal_Arch_s));
|
||||
if (!duhd.au_arches) {
|
||||
*errcode = DW_DLE_ALLOC_FAIL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (locoffsetsize == 32) {
|
||||
struct fat_arch * fa = 0;
|
||||
fa = (struct fat_arch *)calloc(duhd.au_count,
|
||||
sizeof(struct fat_arch));
|
||||
if (!fa) {
|
||||
*errcode = DW_DLE_ALLOC_FAIL;
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
free(fa);
|
||||
return res;
|
||||
}
|
||||
res = RRMOA(fd,fa,/*offset=*/sizeof(fh),
|
||||
duhd.au_count*sizeof(*fa),
|
||||
dw_filesize,errcode);
|
||||
if (res != DW_DLV_OK) {
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
free(fa);
|
||||
return res;
|
||||
}
|
||||
res = fill_in_uni_arch_32(fa,&duhd,word_swap);
|
||||
if (res != DW_DLV_OK) {
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
free(fa);
|
||||
return res;
|
||||
}
|
||||
free(fa);
|
||||
fa = 0;
|
||||
} else { /* 64 */
|
||||
struct fat_arch_64 * fa = 0;
|
||||
fa = (struct fat_arch_64 *)calloc(duhd.au_count,
|
||||
sizeof(struct fat_arch));
|
||||
if (!fa) {
|
||||
*errcode = DW_DLE_ALLOC_FAIL;
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
return res;
|
||||
}
|
||||
res = RRMOA(fd,fa,/*offset*/sizeof(fh),
|
||||
duhd.au_count*sizeof(fa),
|
||||
dw_filesize,errcode);
|
||||
if (res == DW_DLV_ERROR) {
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
free(fa);
|
||||
return res;
|
||||
}
|
||||
res = fill_in_uni_arch_64(fa,&duhd,word_swap);
|
||||
if (res != DW_DLV_OK) {
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
return res;
|
||||
}
|
||||
free(fa);
|
||||
fa = 0;
|
||||
}
|
||||
|
||||
duhdp = malloc(sizeof(*duhdp));
|
||||
if (!duhdp) {
|
||||
free(duhd.au_arches);
|
||||
duhd.au_arches = 0;
|
||||
*errcode = DW_DLE_ALLOC_FAIL;
|
||||
return res;
|
||||
}
|
||||
memcpy(duhdp,&duhd,sizeof(duhd));
|
||||
*dw_contentcount = duhd.au_count;
|
||||
duhdp->au_arches = duhd.au_arches;
|
||||
*dw_head = duhdp;
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
print_arch_item(unsigned int i,
|
||||
struct Dwarf_Universal_Arch_s* arch)
|
||||
{
|
||||
printf(" Universal Binary Index " LONGESTUFMT "\n",i);
|
||||
printf(" cpu " LONGESTXFMT "\n",arch->au_cputype);
|
||||
printf(" cpusubt " LONGESTXFMT "\n",arch->au_cpusubtype);
|
||||
printf(" offset " LONGESTXFMT "\n",arch->au_offset);
|
||||
printf(" size " LONGESTXFMT "\n",arch->au_size);
|
||||
printf(" align " LONGESTXFMT "\n",arch->au_align);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
_dwarf_object_detector_universal_instance(
|
||||
Dwarf_Universal_Head dw_head,
|
||||
Dwarf_Unsigned dw_index_of,
|
||||
Dwarf_Unsigned *dw_cpu_type,
|
||||
Dwarf_Unsigned *dw_cpusubtype,
|
||||
Dwarf_Unsigned *dw_offset,
|
||||
Dwarf_Unsigned *dw_size,
|
||||
Dwarf_Unsigned *dw_align,
|
||||
int *errcode)
|
||||
{
|
||||
struct Dwarf_Universal_Arch_s* arch = 0;
|
||||
|
||||
if (!dw_head) {
|
||||
printf("Missing argument to "
|
||||
"dwarf_object_detector_universal_instance");
|
||||
*errcode = DW_DLE_UNIVERSAL_BINARY_ERROR;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (dw_index_of >= dw_head->au_count){
|
||||
printf("Requested index 0x%lu"
|
||||
" to specific binary "
|
||||
"is too larg: valid: 0 to 0x%lu\n",
|
||||
(unsigned long)dw_index_of,
|
||||
(unsigned long)dw_head->au_count);
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
arch = dw_head->au_arches +dw_index_of;
|
||||
*dw_cpu_type = arch->au_cputype;
|
||||
*dw_cpusubtype = arch->au_cpusubtype;
|
||||
*dw_offset = arch->au_offset;
|
||||
*dw_size = arch->au_size;
|
||||
*dw_align = arch->au_align;
|
||||
#if 0
|
||||
print_arch_item(dw_index_of,arch);
|
||||
#endif
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
void
|
||||
_dwarf_dealloc_universal_head(Dwarf_Universal_Head dw_head)
|
||||
{
|
||||
if (!dw_head) {
|
||||
return;
|
||||
}
|
||||
free(dw_head->au_arches);
|
||||
dw_head->au_arches = 0;
|
||||
free(dw_head);
|
||||
}
|
||||
|
||||
20
bundled/libdwarf/dwarf_machoread.h
vendored
20
bundled/libdwarf/dwarf_machoread.h
vendored
@ -33,6 +33,22 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#ifndef DWARF_MACHOREAD_H
|
||||
#define DWARF_MACHOREAD_H
|
||||
|
||||
struct Dwarf_Universal_Arch_s;
|
||||
struct Dwarf_Universal_Head_s {
|
||||
Dwarf_Unsigned au_magic;
|
||||
Dwarf_Unsigned au_count;
|
||||
struct Dwarf_Universal_Arch_s * au_arches;
|
||||
|
||||
};
|
||||
struct Dwarf_Universal_Arch_s {
|
||||
Dwarf_Unsigned au_cputype;
|
||||
Dwarf_Unsigned au_cpusubtype;
|
||||
Dwarf_Unsigned au_offset;
|
||||
Dwarf_Unsigned au_size;
|
||||
Dwarf_Unsigned au_align;
|
||||
Dwarf_Unsigned au_reserved;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
@ -102,12 +118,14 @@ typedef struct dwarf_macho_filedata_s {
|
||||
const char * mo_path; /* libdwarf must free.*/
|
||||
int mo_fd;
|
||||
int mo_destruct_close_fd; /*aka: lib owns fd */
|
||||
int mo_is_64bit;
|
||||
Dwarf_Unsigned mo_filesize;
|
||||
Dwarf_Unsigned mo_inner_offset; /* for universal inner */
|
||||
Dwarf_Small mo_offsetsize; /* 32 or 64 section data */
|
||||
Dwarf_Small mo_pointersize;
|
||||
int mo_ftype;
|
||||
Dwarf_Small mo_endian;
|
||||
unsigned mo_uninumber; /* for universal binary */
|
||||
unsigned mo_universal_count; /* for universal binary*/
|
||||
/*Dwarf_Small mo_machine; */
|
||||
void (*mo_copy_word) (void *, const void *, unsigned long);
|
||||
|
||||
|
||||
81
bundled/libdwarf/dwarf_object_detector.c
vendored
81
bundled/libdwarf/dwarf_object_detector.c
vendored
@ -56,6 +56,7 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "dwarf_memcpy_swap.h"
|
||||
#include "dwarf_object_read_common.h"
|
||||
#include "dwarf_object_detector.h"
|
||||
#include "dwarf_macho_loader.h"
|
||||
#include "dwarf_string.h"
|
||||
|
||||
#ifndef O_BINARY
|
||||
@ -431,6 +432,39 @@ is_pe_object(int fd,
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
static int
|
||||
is_mach_o_universal(struct elf_header *h,
|
||||
unsigned *endian,
|
||||
unsigned *offsetsize)
|
||||
{
|
||||
unsigned long magicval = 0;
|
||||
unsigned locendian = 0;
|
||||
unsigned locoffsetsize = 0;
|
||||
|
||||
/* No swapping here. Need to match size of
|
||||
the universal-object magic field. */
|
||||
magicval = magic_copy(h->e_ident,4);
|
||||
if (magicval == FAT_MAGIC) {
|
||||
locendian = DW_END_big;
|
||||
locoffsetsize = 32;
|
||||
} else if (magicval == FAT_CIGAM) {
|
||||
locendian = DW_END_little;
|
||||
locoffsetsize = 32;
|
||||
}else if (magicval == FAT_MAGIC_64) {
|
||||
locendian = DW_END_big;
|
||||
locoffsetsize = 64;
|
||||
} else if (magicval == FAT_CIGAM_64) {
|
||||
locendian = DW_END_little;
|
||||
locoffsetsize = 64;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
*endian = locendian;
|
||||
*offsetsize = locoffsetsize;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
is_mach_o_magic(struct elf_header *h,
|
||||
unsigned *endian,
|
||||
@ -470,6 +504,25 @@ dwarf_object_detector_fd(int fd,
|
||||
unsigned *offsetsize,
|
||||
Dwarf_Unsigned *filesize,
|
||||
int *errcode)
|
||||
{
|
||||
Dwarf_Unsigned fileoffsetbase = 0;
|
||||
int res = 0;
|
||||
|
||||
res = _dwarf_object_detector_fd_a(fd,
|
||||
ftype,endian,offsetsize,
|
||||
fileoffsetbase,filesize,
|
||||
errcode);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
_dwarf_object_detector_fd_a(int fd,
|
||||
unsigned *ftype,
|
||||
unsigned *endian,
|
||||
unsigned *offsetsize,
|
||||
Dwarf_Unsigned fileoffsetbase,
|
||||
Dwarf_Unsigned *filesize,
|
||||
int *errcode)
|
||||
{
|
||||
struct elf_header h;
|
||||
size_t readlen = sizeof(h);
|
||||
@ -477,6 +530,7 @@ dwarf_object_detector_fd(int fd,
|
||||
off_t fsize = 0;
|
||||
off_t lsval = 0;
|
||||
ssize_t readval = 0;
|
||||
Dwarf_Unsigned remaininglen = 0;
|
||||
|
||||
fsize = lseek(fd,0L,SEEK_END);
|
||||
if (fsize < 0) {
|
||||
@ -488,7 +542,19 @@ dwarf_object_detector_fd(int fd,
|
||||
*errcode = DW_DLE_FILE_TOO_SMALL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
lsval = lseek(fd,0L,SEEK_SET);
|
||||
remaininglen = fsize - fileoffsetbase;
|
||||
if ((Dwarf_Unsigned)fsize <= fileoffsetbase) {
|
||||
printf("FAIL: fsize <= offsetbase impossible\n");
|
||||
*errcode = DW_DLE_SEEK_ERROR;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
if (remaininglen <= readlen) {
|
||||
/* Not a real object file */
|
||||
*errcode = DW_DLE_FILE_TOO_SMALL;
|
||||
return DW_DLV_ERROR;
|
||||
}
|
||||
|
||||
lsval = lseek(fd,fileoffsetbase,SEEK_SET);
|
||||
if (lsval < 0) {
|
||||
*errcode = DW_DLE_SEEK_ERROR;
|
||||
return DW_DLV_ERROR;
|
||||
@ -509,23 +575,28 @@ dwarf_object_detector_fd(int fd,
|
||||
return res;
|
||||
}
|
||||
*ftype = DW_FTYPE_ELF;
|
||||
*filesize = (size_t)fsize;
|
||||
*filesize = (Dwarf_Unsigned)fsize;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (is_mach_o_universal(&h,endian,offsetsize)) {
|
||||
*ftype = DW_FTYPE_APPLEUNIVERSAL;
|
||||
*filesize = (Dwarf_Unsigned)fsize;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (is_mach_o_magic(&h,endian,offsetsize)) {
|
||||
*ftype = DW_FTYPE_MACH_O;
|
||||
*filesize = (size_t)fsize;
|
||||
*filesize = (Dwarf_Unsigned)fsize;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
if (is_archive_magic(&h)) {
|
||||
*ftype = DW_FTYPE_ARCHIVE;
|
||||
*filesize = (size_t)fsize;
|
||||
*filesize = (Dwarf_Unsigned)fsize;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
res = is_pe_object(fd,fsize,endian,offsetsize,errcode);
|
||||
if (res == DW_DLV_OK ) {
|
||||
*ftype = DW_FTYPE_PE;
|
||||
*filesize = (size_t)fsize;
|
||||
*filesize = (Dwarf_Unsigned)fsize;
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
/* Unknown object format. */
|
||||
|
||||
9
bundled/libdwarf/dwarf_object_detector.h
vendored
9
bundled/libdwarf/dwarf_object_detector.h
vendored
@ -76,6 +76,15 @@ extern "C" {
|
||||
*errcode when the function returns DW_DLV_ERROR)
|
||||
will hopefully suffice for most purposes. */
|
||||
|
||||
/* Added September 2023 for Mach-O universal binaries */
|
||||
int _dwarf_object_detector_fd_a(int dw_fd,
|
||||
unsigned int *dw_ftype,
|
||||
unsigned int *dw_endian,
|
||||
unsigned int *dw_offsetsize,
|
||||
Dwarf_Unsigned dw_offset_base,
|
||||
Dwarf_Unsigned *dw_filesize,
|
||||
int *dw_errcode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
12
bundled/libdwarf/dwarf_opaque.h
vendored
12
bundled/libdwarf/dwarf_opaque.h
vendored
@ -594,6 +594,7 @@ struct Dwarf_Debug_s {
|
||||
under de_obj_file. */
|
||||
int de_fd;
|
||||
char de_owns_fd;
|
||||
char de_in_tdestroy; /* for de_alloc_tree DW202309-001 */
|
||||
/* DW_PATHSOURCE_BASIC or MACOS or DEBUGLINK */
|
||||
unsigned char de_path_source;
|
||||
/* de_path is only set automatically if dwarf_init_path()
|
||||
@ -753,6 +754,14 @@ struct Dwarf_Debug_s {
|
||||
Dwarf_Unsigned de_frame_same_value_number;
|
||||
Dwarf_Unsigned de_frame_undefined_value_number;
|
||||
|
||||
/* If count > 0 means the DW_FTYPE_APPLEUNIVERSAL
|
||||
we initially read has this number of
|
||||
binaries in it, and de_universalbinary_index
|
||||
is the index of the current object inside
|
||||
the universal binary. */
|
||||
unsigned int de_universalbinary_count;
|
||||
unsigned int de_universalbinary_index;
|
||||
|
||||
unsigned char de_big_endian_object; /* Non-zero if
|
||||
object being read is big-endian. */
|
||||
|
||||
@ -1010,10 +1019,11 @@ void _dwarf_destruct_elf_nlaccess(
|
||||
|
||||
extern int _dwarf_macho_setup(int fd,
|
||||
char *true_path,
|
||||
unsigned universalnumber,
|
||||
unsigned ftype,
|
||||
unsigned endian,
|
||||
unsigned offsetsize,
|
||||
size_t filesize,
|
||||
Dwarf_Unsigned filesize,
|
||||
unsigned groupnumber,
|
||||
Dwarf_Handler errhand,
|
||||
Dwarf_Ptr errarg,
|
||||
|
||||
22
bundled/libdwarf/dwarf_query.c
vendored
22
bundled/libdwarf/dwarf_query.c
vendored
@ -2106,3 +2106,25 @@ int dwarf_cu_header_basics(Dwarf_Die die,
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_get_universalbinary_count(
|
||||
Dwarf_Debug dbg,
|
||||
Dwarf_Unsigned *current_index,
|
||||
Dwarf_Unsigned *available_count)
|
||||
{
|
||||
if (!dbg) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (!dbg->de_universalbinary_count ) {
|
||||
return DW_DLV_NO_ENTRY;
|
||||
}
|
||||
if (current_index) {
|
||||
*current_index = dbg->de_universalbinary_index;
|
||||
}
|
||||
if (available_count) {
|
||||
*available_count = dbg->de_universalbinary_count;
|
||||
}
|
||||
return DW_DLV_OK;
|
||||
}
|
||||
|
||||
|
||||
3
bundled/libdwarf/dwarf_rnglists.c
vendored
3
bundled/libdwarf/dwarf_rnglists.c
vendored
@ -1274,6 +1274,9 @@ int
|
||||
dwarf_rnglists_get_rle_head(
|
||||
Dwarf_Attribute attr,
|
||||
Dwarf_Half theform,
|
||||
/* attr_val is either an offset
|
||||
(theform == DW_FORM_sec_offset)
|
||||
or an index DW_FORM_rnglistx. */
|
||||
Dwarf_Unsigned attr_val,
|
||||
Dwarf_Rnglists_Head *head_out,
|
||||
Dwarf_Unsigned *entries_count_out,
|
||||
|
||||
63
bundled/libdwarf/dwarf_universal.h
vendored
Normal file
63
bundled/libdwarf/dwarf_universal.h
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (c) 2023, David Anderson
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with
|
||||
or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef DWARF_UNIVERSAL_H
|
||||
#define DWARF_UNIVERSAL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
struct Dwarf_Universal_Head_s;
|
||||
typedef struct Dwarf_Universal_Head_s * Dwarf_Universal_Head;
|
||||
|
||||
int _dwarf_object_detector_universal_head(
|
||||
char *dw_path,
|
||||
Dwarf_Unsigned dw_filesize,
|
||||
unsigned int *dw_contentcount,
|
||||
Dwarf_Universal_Head * dw_head,
|
||||
int *errcode);
|
||||
|
||||
int _dwarf_object_detector_universal_instance(
|
||||
Dwarf_Universal_Head dw_head,
|
||||
Dwarf_Unsigned dw_index_of,
|
||||
Dwarf_Unsigned *dw_cpu_type,
|
||||
Dwarf_Unsigned *dw_cpu_subtype,
|
||||
Dwarf_Unsigned *dw_offset,
|
||||
Dwarf_Unsigned *dw_size,
|
||||
Dwarf_Unsigned *dw_align,
|
||||
int *errcode);
|
||||
void _dwarf_dealloc_universal_head(Dwarf_Universal_Head dw_head);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* DWARF_UNIVERSAL_H */
|
||||
117
bundled/libdwarf/libdwarf.h
vendored
117
bundled/libdwarf/libdwarf.h
vendored
@ -99,10 +99,10 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/* Semantic Version identity for this libdwarf.h */
|
||||
#define DW_LIBDWARF_VERSION "0.8.0"
|
||||
#define DW_LIBDWARF_VERSION "0.8.1"
|
||||
#define DW_LIBDWARF_VERSION_MAJOR 0
|
||||
#define DW_LIBDWARF_VERSION_MINOR 8
|
||||
#define DW_LIBDWARF_VERSION_MICRO 0
|
||||
#define DW_LIBDWARF_VERSION_MICRO 1
|
||||
|
||||
#define DW_PATHSOURCE_unspecified 0
|
||||
#define DW_PATHSOURCE_basic 1
|
||||
@ -115,6 +115,7 @@ extern "C" {
|
||||
#define DW_FTYPE_MACH_O 2 /* MacOS. */
|
||||
#define DW_FTYPE_PE 3 /* Windows */
|
||||
#define DW_FTYPE_ARCHIVE 4 /* unix archive */
|
||||
#define DW_FTYPE_APPLEUNIVERSAL 5
|
||||
#endif /* DW_FTYPE_UNKNOWN */
|
||||
/* standard return values for functions */
|
||||
#define DW_DLV_NO_ENTRY -1
|
||||
@ -1385,9 +1386,10 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head;
|
||||
#define DW_DLE_LINE_INDEX_WRONG 499
|
||||
#define DW_DLE_LINE_COUNT_WRONG 500
|
||||
#define DW_DLE_ARITHMETIC_OVERFLOW 501
|
||||
#define DW_DLE_UNIVERSAL_BINARY_ERROR 502
|
||||
|
||||
/*! @note DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
|
||||
#define DW_DLE_LAST 501
|
||||
#define DW_DLE_LAST 502
|
||||
#define DW_DLE_LO_USER 0x10000
|
||||
/*! @} */
|
||||
|
||||
@ -1403,6 +1405,10 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head;
|
||||
/*! @brief Initialization based on path, the most common
|
||||
initialization.
|
||||
|
||||
On a Mach-O universal binary this function can
|
||||
only return information about the first (zero index)
|
||||
object in the universal binary.
|
||||
|
||||
@param dw_path
|
||||
Pass in the path to the object file to open.
|
||||
@param dw_true_path_out_buffer
|
||||
@ -1448,6 +1454,8 @@ typedef struct Dwarf_Rnglists_Head_s * Dwarf_Rnglists_Head;
|
||||
@see dwarf_init_path_dl dwarf_init_b
|
||||
@see exampleinit
|
||||
*/
|
||||
|
||||
|
||||
DW_API int dwarf_init_path(const char * dw_path,
|
||||
char * dw_true_path_out_buffer,
|
||||
unsigned int dw_true_path_bufferlen,
|
||||
@ -1457,6 +1465,28 @@ DW_API int dwarf_init_path(const char * dw_path,
|
||||
Dwarf_Debug* dw_dbg,
|
||||
Dwarf_Error* dw_error);
|
||||
|
||||
/*! @brief Initialization based on path
|
||||
|
||||
This identical to dwarf_init_path() except that it
|
||||
adds a new argument, dw_universalnumber,
|
||||
with which you can specify which object in
|
||||
a Mach-O universal binary you wish to open.
|
||||
|
||||
It is always safe and appropriate to pass
|
||||
zero as the dw_universalnumber.
|
||||
Elf and PE and (non-universal) Mach-O object
|
||||
files ignore the value of dw_universalnumber.
|
||||
*/
|
||||
DW_API int dwarf_init_path_a(const char * dw_path,
|
||||
char * dw_true_path_out_buffer,
|
||||
unsigned int dw_true_path_bufferlen,
|
||||
unsigned int dw_groupnumber,
|
||||
unsigned int dw_universalnumber,
|
||||
Dwarf_Handler dw_errhand,
|
||||
Dwarf_Ptr dw_errarg,
|
||||
Dwarf_Debug* dw_dbg,
|
||||
Dwarf_Error* dw_error);
|
||||
|
||||
/*! @brief Initialization following GNU debuglink section data.
|
||||
|
||||
Sets the true-path with DWARF if there is
|
||||
@ -1525,6 +1555,35 @@ DW_API int dwarf_init_path_dl(const char * dw_path,
|
||||
unsigned char * dw_dl_path_source,
|
||||
Dwarf_Error* dw_error);
|
||||
|
||||
/*! @brief Initialization based on path with debuglink
|
||||
|
||||
This identical to dwarf_init_path_dl() except that it
|
||||
adds a new argument, dw_universalnumber,
|
||||
with which you can specify which object in
|
||||
a Mach-O universal binary you wish to open.
|
||||
|
||||
It is always safe and appropriate to pass
|
||||
zero as the dw_universalnumber.
|
||||
Elf and PE and (non-universal) Mach-O object
|
||||
files ignore the value of dw_universalnumber.
|
||||
|
||||
Mach-O objects do not contain or use debuglink
|
||||
data.
|
||||
*/
|
||||
|
||||
DW_API int dwarf_init_path_dl_a(const char * dw_path,
|
||||
char * dw_true_path_out_buffer,
|
||||
unsigned int dw_true_path_bufferlen,
|
||||
unsigned int dw_groupnumber,
|
||||
unsigned int dw_universalnumber,
|
||||
Dwarf_Handler dw_errhand,
|
||||
Dwarf_Ptr dw_errarg,
|
||||
Dwarf_Debug* dw_dbg,
|
||||
char ** dw_dl_path_array,
|
||||
unsigned int dw_dl_path_array_size,
|
||||
unsigned char * dw_dl_path_source,
|
||||
Dwarf_Error* dw_error);
|
||||
|
||||
/*! @brief Initialization based on Unix/Linux (etc) path
|
||||
This version allows specifying any number of debuglink
|
||||
global paths to search on for debuglink targets.
|
||||
@ -3964,7 +4023,8 @@ DW_API void dwarf_dealloc_ranges(Dwarf_Debug dw_dbg,
|
||||
@param dw_attr
|
||||
The attribute referring to .debug_rnglists
|
||||
@param dw_theform
|
||||
The form number.
|
||||
The form number, DW_FORM_sec_offset or
|
||||
DW_FORM_rnglistx.
|
||||
@param dw_index_or_offset_value
|
||||
If the form is an index, pass it here.
|
||||
If the form is an offset, pass that here.
|
||||
@ -5401,7 +5461,7 @@ DW_API int dwarf_get_fde_info_for_reg3_b(Dwarf_Fde dw_fde,
|
||||
dwarf_get_fde_info_for_reg3_c but
|
||||
it refers to the CFA (which is not part of the register
|
||||
table) so function has no table column argument.
|
||||
|
||||
|
||||
New in September 2023, release 0.8.0.
|
||||
dwarf_get_fde_info_for_cfa_reg3_c() returns dw_offset
|
||||
as a signed type.
|
||||
@ -5428,13 +5488,13 @@ DW_API int dwarf_get_fde_info_for_cfa_reg3_c(Dwarf_Fde dw_fde,
|
||||
Dwarf_Bool * dw_has_more_rows,
|
||||
Dwarf_Addr * dw_subsequent_pc,
|
||||
Dwarf_Error * dw_error);
|
||||
/*! @brief Get the value of the CFA for a particular pc value(obsolete)
|
||||
/*! @brief Get the value of the CFA for a particular pc value
|
||||
|
||||
@see dwarf_get_fde_info_for_cfa_reg3_c
|
||||
This is the earlier version that returns a dw_offset
|
||||
of Dwarf_Unsigned, requiring you to cast to Dwarf_Signed
|
||||
to work with the value.
|
||||
|
||||
This is the earlier version that returns a dw_offset
|
||||
of type Dwarf_Unsigned, requiring you to cast to Dwarf_Signed
|
||||
to work with the value.
|
||||
|
||||
*/
|
||||
DW_API int dwarf_get_fde_info_for_cfa_reg3_b(Dwarf_Fde dw_fde,
|
||||
@ -8846,11 +8906,50 @@ DW_API Dwarf_Small dwarf_set_default_address_size(
|
||||
Dwarf_Debug dw_dbg,
|
||||
Dwarf_Small dw_value);
|
||||
|
||||
/*! @brief Retrieve universal binary index
|
||||
|
||||
For Mach-O universal binaries this returns
|
||||
relevant information.
|
||||
|
||||
For non-universal binaries (Mach-O, Elf,
|
||||
or PE) the values are not meaningful, so
|
||||
the function returns DW_DLV_NO_ENTRY..
|
||||
|
||||
@param dw_dbg
|
||||
The Dwarf_Debug of interest.
|
||||
@param dw_current_index
|
||||
If dw_current_index is passed in non-null the function
|
||||
returns the universal-binary index of the current
|
||||
object (which came from a universal binary).
|
||||
@param dw_available_count
|
||||
If dw_current_index is passed in non-null the function
|
||||
returns the count of binaries in
|
||||
the universal binary.
|
||||
@return
|
||||
Returns DW_DLV_NO_ENTRY if the object file is
|
||||
not from a Mach-O universal binary.
|
||||
Returns DW_DLV_NO_ENTRY if dw_dbg is passed in NULL.
|
||||
Never returns DW_DLV_ERROR.
|
||||
*/
|
||||
DW_API int dwarf_get_universalbinary_count(
|
||||
Dwarf_Debug dw_dbg,
|
||||
Dwarf_Unsigned *dw_current_index,
|
||||
Dwarf_Unsigned *dw_available_count);
|
||||
|
||||
|
||||
/*! @}
|
||||
*/
|
||||
|
||||
/*! @defgroup objectdetector Determine Object Type of a File
|
||||
@{
|
||||
|
||||
This group of functions are unlikely to be called
|
||||
by your code unless your code needs to know
|
||||
the basic data about an object file without
|
||||
actually opening a Dwarf_Debug.
|
||||
|
||||
These are crucial for libdwarf itself.
|
||||
|
||||
*/
|
||||
DW_API int dwarf_object_detector_path_b(const char * dw_path,
|
||||
char *dw_outpath_buffer,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user