Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
libbacktrace
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
libbacktrace
Commits
4e548e73
Commit
4e548e73
authored
Feb 18, 2020
by
Ian Lance Taylor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
libbacktrace: add preliminary Mach-O support
parent
929d6205
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1561 additions
and
49 deletions
+1561
-49
Makefile.am
Makefile.am
+65
-3
Makefile.in
Makefile.in
+87
-36
config.h.in
config.h.in
+3
-0
configure
configure
+75
-3
configure.ac
configure.ac
+10
-0
filetype.awk
filetype.awk
+12
-7
macho.c
macho.c
+1309
-0
No files found.
Makefile.am
View file @
4e548e73
...
@@ -57,6 +57,7 @@ BACKTRACE_FILES = \
...
@@ -57,6 +57,7 @@ BACKTRACE_FILES = \
FORMAT_FILES
=
\
FORMAT_FILES
=
\
elf.c
\
elf.c
\
macho.c
\
pecoff.c
\
pecoff.c
\
unknown.c
\
unknown.c
\
xcoff.c
xcoff.c
...
@@ -85,18 +86,28 @@ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
...
@@ -85,18 +86,28 @@ libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
# Testsuite.
# Testsuite.
# Add
test to this variable, if you want it to be build
.
# Add
a test to this variable if you want it to be built
.
check_PROGRAMS
=
check_PROGRAMS
=
# Add
test to this variable,
if you want it to be run.
# Add
a test to this variable
if you want it to be run.
TESTS
=
TESTS
=
# Add
test to this variable, if you want it to be build
and run.
# Add
a test to this variable if you want it to be built
and run.
BUILDTESTS
=
BUILDTESTS
=
# Add a file to this variable if you want it to be built for testing.
check_DATA
=
# Flags to use when compiling test programs.
# Flags to use when compiling test programs.
libbacktrace_TEST_CFLAGS
=
$(EXTRA_FLAGS)
$(WARN_FLAGS)
-g
libbacktrace_TEST_CFLAGS
=
$(EXTRA_FLAGS)
$(WARN_FLAGS)
-g
if
HAVE_DSYMUTIL
%.dSYM
:
%
$(DSYMUTIL)
$<
endif
HAVE_DSYMUTIL
if
NATIVE
if
NATIVE
check_LTLIBRARIES
=
libbacktrace_alloc.la
check_LTLIBRARIES
=
libbacktrace_alloc.la
...
@@ -164,6 +175,12 @@ test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
...
@@ -164,6 +175,12 @@ test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
BUILDTESTS
+=
test_elf_64
BUILDTESTS
+=
test_elf_64
test_macho_SOURCES
=
test_format.c testlib.c
test_macho_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
test_macho_LDADD
=
libbacktrace_noformat.la macho.lo
BUILDTESTS
+=
test_macho
test_xcoff_32_SOURCES
=
test_format.c testlib.c
test_xcoff_32_SOURCES
=
test_format.c testlib.c
test_xcoff_32_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
test_xcoff_32_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
test_xcoff_32_LDADD
=
libbacktrace_noformat.la xcoff_32.lo
test_xcoff_32_LDADD
=
libbacktrace_noformat.la xcoff_32.lo
...
@@ -221,6 +238,10 @@ allocfail.sh: allocfail
...
@@ -221,6 +238,10 @@ allocfail.sh: allocfail
TESTS
+=
allocfail.sh
TESTS
+=
allocfail.sh
if
HAVE_DSYMUTIL
check_DATA
+=
allocfail.dSYM
endif
HAVE_DSYMUTIL
if
HAVE_ELF
if
HAVE_ELF
if
HAVE_OBJCOPY_DEBUGLINK
if
HAVE_OBJCOPY_DEBUGLINK
...
@@ -253,6 +274,10 @@ btest_LDADD = libbacktrace.la
...
@@ -253,6 +274,10 @@ btest_LDADD = libbacktrace.la
BUILDTESTS
+=
btest
BUILDTESTS
+=
btest
if
HAVE_DSYMUTIL
check_DATA
+=
btest.dSYM
endif
HAVE_DSYMUTIL
if
HAVE_ELF
if
HAVE_ELF
btest_lto_SOURCES
=
btest.c testlib.c
btest_lto_SOURCES
=
btest.c testlib.c
...
@@ -269,6 +294,10 @@ btest_alloc_LDADD = libbacktrace_alloc.la
...
@@ -269,6 +294,10 @@ btest_alloc_LDADD = libbacktrace_alloc.la
BUILDTESTS
+=
btest_alloc
BUILDTESTS
+=
btest_alloc
if
HAVE_DSYMUTIL
check_DATA
+=
btest_alloc.dSYM
endif
HAVE_DSYMUTIL
if
HAVE_DWZ
if
HAVE_DWZ
%_dwz
:
%
%_dwz
:
%
...
@@ -295,12 +324,20 @@ stest_LDADD = libbacktrace.la
...
@@ -295,12 +324,20 @@ stest_LDADD = libbacktrace.la
BUILDTESTS
+=
stest
BUILDTESTS
+=
stest
if
HAVE_DSYMUTIL
check_DATA
+=
stest.dSYM
endif
HAVE_DSYMUTIL
stest_alloc_SOURCES
=
$(stest_SOURCES)
stest_alloc_SOURCES
=
$(stest_SOURCES)
stest_alloc_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
stest_alloc_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
stest_alloc_LDADD
=
libbacktrace_alloc.la
stest_alloc_LDADD
=
libbacktrace_alloc.la
BUILDTESTS
+=
stest_alloc
BUILDTESTS
+=
stest_alloc
if
HAVE_DSYMUTIL
check_DATA
+=
stest_alloc.dSYM
endif
HAVE_DSYMUTIL
if
HAVE_ELF
if
HAVE_ELF
ztest_SOURCES
=
ztest.c testlib.c
ztest_SOURCES
=
ztest.c testlib.c
...
@@ -330,10 +367,18 @@ edtest_LDADD = libbacktrace.la
...
@@ -330,10 +367,18 @@ edtest_LDADD = libbacktrace.la
BUILDTESTS
+=
edtest
BUILDTESTS
+=
edtest
if
HAVE_DSYMUTIL
check_DATA
+=
edtest.dSYM
endif
HAVE_DSYMUTIL
edtest_alloc_SOURCES
=
$(edtest_SOURCES)
edtest_alloc_SOURCES
=
$(edtest_SOURCES)
edtest_alloc_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
edtest_alloc_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
edtest_alloc_LDADD
=
libbacktrace_alloc.la
edtest_alloc_LDADD
=
libbacktrace_alloc.la
if
HAVE_DSYMUTIL
check_DATA
+=
edtest_alloc.dSYM
endif
HAVE_DSYMUTIL
BUILDTESTS
+=
edtest_alloc
BUILDTESTS
+=
edtest_alloc
edtest2_build.c
:
gen_edtest2_build; @true
edtest2_build.c
:
gen_edtest2_build; @true
...
@@ -350,12 +395,20 @@ ttest_SOURCES = ttest.c testlib.c
...
@@ -350,12 +395,20 @@ ttest_SOURCES = ttest.c testlib.c
ttest_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
-pthread
ttest_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
-pthread
ttest_LDADD
=
libbacktrace.la
ttest_LDADD
=
libbacktrace.la
if
HAVE_DSYMUTIL
check_DATA
+=
ttest.dSYM
endif
HAVE_DSYMUTIL
BUILDTESTS
+=
ttest_alloc
BUILDTESTS
+=
ttest_alloc
ttest_alloc_SOURCES
=
$(ttest_SOURCES)
ttest_alloc_SOURCES
=
$(ttest_SOURCES)
ttest_alloc_CFLAGS
=
$(ttest_CFLAGS)
ttest_alloc_CFLAGS
=
$(ttest_CFLAGS)
ttest_alloc_LDADD
=
libbacktrace_alloc.la
ttest_alloc_LDADD
=
libbacktrace_alloc.la
if
HAVE_DSYMUTIL
check_DATA
+=
ttest_alloc.dSYM
endif
HAVE_DSYMUTIL
endif
HAVE_PTHREAD
endif
HAVE_PTHREAD
if
HAVE_OBJCOPY_DEBUGLINK
if
HAVE_OBJCOPY_DEBUGLINK
...
@@ -410,12 +463,20 @@ dwarf5_LDADD = libbacktrace.la
...
@@ -410,12 +463,20 @@ dwarf5_LDADD = libbacktrace.la
BUILDTESTS
+=
dwarf5
BUILDTESTS
+=
dwarf5
if
HAVE_DSYMUTIL
check_DATA
+=
dwarf5.dSYM
endif
HAVE_DSYMUTIL
dwarf5_alloc_SOURCES
=
$(dwarf5_SOURCES)
dwarf5_alloc_SOURCES
=
$(dwarf5_SOURCES)
dwarf5_alloc_CFLAGS
=
$(dwarf5_CFLAGS)
dwarf5_alloc_CFLAGS
=
$(dwarf5_CFLAGS)
dwarf5_alloc_LDADD
=
libbacktrace_alloc.la
dwarf5_alloc_LDADD
=
libbacktrace_alloc.la
BUILDTESTS
+=
dwarf5_alloc
BUILDTESTS
+=
dwarf5_alloc
if
HAVE_DSYMUTIL
check_DATA
+=
dwarf5_alloc.dSYM
endif
HAVE_DSYMUTIL
endif
endif
endif
NATIVE
endif
NATIVE
...
@@ -447,6 +508,7 @@ btest.lo: filenames.h backtrace.h backtrace-supported.h
...
@@ -447,6 +508,7 @@ btest.lo: filenames.h backtrace.h backtrace-supported.h
dwarf.lo
:
config.h filenames.h backtrace.h internal.h
dwarf.lo
:
config.h filenames.h backtrace.h internal.h
elf.lo
:
config.h backtrace.h internal.h
elf.lo
:
config.h backtrace.h internal.h
fileline.lo
:
config.h backtrace.h internal.h
fileline.lo
:
config.h backtrace.h internal.h
macho.lo
:
config.h backtrace.h internal.h
mmap.lo
:
config.h backtrace.h internal.h
mmap.lo
:
config.h backtrace.h internal.h
mmapio.lo
:
config.h backtrace.h internal.h
mmapio.lo
:
config.h backtrace.h internal.h
nounwind.lo
:
config.h internal.h
nounwind.lo
:
config.h internal.h
...
...
Makefile.in
View file @
4e548e73
...
@@ -123,33 +123,41 @@ host_triplet = @host@
...
@@ -123,33 +123,41 @@ host_triplet = @host@
target_triplet
=
@target@
target_triplet
=
@target@
check_PROGRAMS
=
$(am__EXEEXT_1)
$(am__EXEEXT_2)
$(am__EXEEXT_3)
\
check_PROGRAMS
=
$(am__EXEEXT_1)
$(am__EXEEXT_2)
$(am__EXEEXT_3)
\
$(am__EXEEXT_12)
$(am__EXEEXT_12)
TESTS
=
$(am__append_4)
$(am__append_
6)
$(am__append_8
)
\
TESTS
=
$(am__append_4)
$(am__append_
7)
$(am__append_9
)
\
$(am__append_1
1)
$(am__append_12)
$(am__append_18
)
\
$(am__append_1
2)
$(am__append_13)
$(am__append_20
)
\
$(am__EXEEXT_12)
$(am__EXEEXT_12)
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_1
=
libbacktrace_elf_for_test.la
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_1
=
libbacktrace_elf_for_test.la
@NATIVE_TRUE@
am__append_2
=
test_elf_32 test_elf_64 test_
xcoff_32
\
@NATIVE_TRUE@
am__append_2
=
test_elf_32 test_elf_64 test_
macho
\
@NATIVE_TRUE@ test_xcoff_
64 test_pecoff test_unknown unittest
\
@NATIVE_TRUE@ test_xcoff_
32 test_xcoff_64 test_pecoff
\
@NATIVE_TRUE@ unittest_alloc btest
@NATIVE_TRUE@
test_unknown unittest
unittest_alloc btest
@NATIVE_TRUE@
am__append_3
=
allocfail
@NATIVE_TRUE@
am__append_3
=
allocfail
@NATIVE_TRUE@
am__append_4
=
allocfail.sh
@NATIVE_TRUE@
am__append_4
=
allocfail.sh
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_5
=
b2test
@HAVE_DSYMUTIL_TRUE@@NATIVE_TRUE@
am__append_5
=
allocfail.dSYM
\
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_6
=
b2test_buildid
@HAVE_DSYMUTIL_TRUE@@NATIVE_TRUE@ btest.dSYM btest_alloc.dSYM
\
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_7
=
b3test
@HAVE_DSYMUTIL_TRUE@@NATIVE_TRUE@ stest.dSYM stest_alloc.dSYM
\
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_8
=
b3test_dwz_buildid
@HAVE_DSYMUTIL_TRUE@@NATIVE_TRUE@ edtest.dSYM edtest_alloc.dSYM
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__append_9
=
btest_lto
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_6
=
b2test
@NATIVE_TRUE@
am__append_10
=
btest_alloc stest stest_alloc
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_7
=
b2test_buildid
@HAVE_DWZ_TRUE@@NATIVE_TRUE@
am__append_11
=
btest_dwz
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_8
=
b3test
@HAVE_DWZ_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_12
=
btest_dwz_gnudebuglink
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_9
=
b3test_dwz_buildid
@HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@
am__append_13
=
-lz
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__append_10
=
btest_lto
@NATIVE_TRUE@
am__append_11
=
btest_alloc stest stest_alloc
@HAVE_DWZ_TRUE@@NATIVE_TRUE@
am__append_12
=
btest_dwz
@HAVE_DWZ_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_13
=
btest_dwz_gnudebuglink
@HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@
am__append_14
=
-lz
@HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@
am__append_14
=
-lz
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__append_15
=
ztest ztest_alloc
@HAVE_ELF_TRUE@@HAVE_ZLIB_TRUE@@NATIVE_TRUE@
am__append_15
=
-lz
@NATIVE_TRUE@
am__append_16
=
edtest edtest_alloc
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__append_16
=
ztest ztest_alloc
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@
am__append_17
=
ttest ttest_alloc
@NATIVE_TRUE@
am__append_17
=
edtest edtest_alloc
@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_18
=
btest_gnudebuglink
@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@
am__append_18
=
ttest ttest_alloc
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@
am__append_19
=
ctestg ctesta
\
@HAVE_DSYMUTIL_TRUE@@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@
am__append_19
=
ttest.dSYM
\
@HAVE_DSYMUTIL_TRUE@@HAVE_PTHREAD_TRUE@@NATIVE_TRUE@ ttest_alloc.dSYM
@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__append_20
=
btest_gnudebuglink
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@
am__append_21
=
ctestg ctesta
\
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc
\
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctestg_alloc
\
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc
@HAVE_COMPRESSED_DEBUG_TRUE@@NATIVE_TRUE@ ctesta_alloc
@HAVE_DWARF5_TRUE@@NATIVE_TRUE@
am__append_20
=
dwarf5 dwarf5_alloc
@HAVE_DWARF5_TRUE@@NATIVE_TRUE@
am__append_22
=
dwarf5 dwarf5_alloc
@HAVE_DSYMUTIL_TRUE@@HAVE_DWARF5_TRUE@@NATIVE_TRUE@
am__append_23
=
dwarf5.dSYM
\
@HAVE_DSYMUTIL_TRUE@@HAVE_DWARF5_TRUE@@NATIVE_TRUE@ dwarf5_alloc.dSYM
subdir
=
.
subdir
=
.
ACLOCAL_M4
=
$(top_srcdir)
/aclocal.m4
ACLOCAL_M4
=
$(top_srcdir)
/aclocal.m4
am__aclocal_m4_deps
=
$(top_srcdir)
/config/lead-dot.m4
\
am__aclocal_m4_deps
=
$(top_srcdir)
/config/lead-dot.m4
\
...
@@ -235,10 +243,10 @@ libbacktrace_noformat_la_OBJECTS = \
...
@@ -235,10 +243,10 @@ libbacktrace_noformat_la_OBJECTS = \
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__EXEEXT_2
=
b2test
$(EXEEXT)
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__EXEEXT_2
=
b2test
$(EXEEXT)
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__EXEEXT_3
=
b3test
$(EXEEXT)
@HAVE_DWZ_TRUE@@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
am__EXEEXT_3
=
b3test
$(EXEEXT)
@NATIVE_TRUE@
am__EXEEXT_4
=
test_elf_32
$(EXEEXT)
test_elf_64
$(EXEEXT)
\
@NATIVE_TRUE@
am__EXEEXT_4
=
test_elf_32
$(EXEEXT)
test_elf_64
$(EXEEXT)
\
@NATIVE_TRUE@ test_
xcoff_32
$(EXEEXT)
test_xcoff_64
$(EXEEXT)
\
@NATIVE_TRUE@ test_
macho
$(EXEEXT)
test_xcoff_32
$(EXEEXT)
\
@NATIVE_TRUE@ test_
pecoff
$(EXEEXT)
test_unknown
$(EXEEXT)
\
@NATIVE_TRUE@ test_
xcoff_64
$(EXEEXT)
test_pecoff
$(EXEEXT)
\
@NATIVE_TRUE@
unittest
$(EXEEXT)
unittest_alloc
$(EXEEXT)
\
@NATIVE_TRUE@
test_unknown
$(EXEEXT)
unittest
$(EXEEXT)
\
@NATIVE_TRUE@ btest
$(EXEEXT)
@NATIVE_TRUE@
unittest_alloc
$(EXEEXT)
btest
$(EXEEXT)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__EXEEXT_5
=
btest_lto
$(EXEEXT)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
am__EXEEXT_5
=
btest_lto
$(EXEEXT)
@NATIVE_TRUE@
am__EXEEXT_6
=
btest_alloc
$(EXEEXT)
stest
$(EXEEXT)
\
@NATIVE_TRUE@
am__EXEEXT_6
=
btest_alloc
$(EXEEXT)
stest
$(EXEEXT)
\
@NATIVE_TRUE@ stest_alloc
$(EXEEXT)
@NATIVE_TRUE@ stest_alloc
$(EXEEXT)
...
@@ -405,6 +413,14 @@ test_elf_64_OBJECTS = $(am_test_elf_64_OBJECTS)
...
@@ -405,6 +413,14 @@ test_elf_64_OBJECTS = $(am_test_elf_64_OBJECTS)
test_elf_64_LINK
=
$(LIBTOOL)
$(AM_V_lt)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
\
test_elf_64_LINK
=
$(LIBTOOL)
$(AM_V_lt)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
\
$(LIBTOOLFLAGS)
--mode
=
link
$(CCLD)
$(test_elf_64_CFLAGS)
\
$(LIBTOOLFLAGS)
--mode
=
link
$(CCLD)
$(test_elf_64_CFLAGS)
\
$(CFLAGS)
$(AM_LDFLAGS)
$(LDFLAGS)
-o
$@
$(CFLAGS)
$(AM_LDFLAGS)
$(LDFLAGS)
-o
$@
@NATIVE_TRUE@
am_test_macho_OBJECTS
=
test_macho-test_format.
$(OBJEXT)
\
@NATIVE_TRUE@ test_macho-testlib.
$(OBJEXT)
test_macho_OBJECTS
=
$(am_test_macho_OBJECTS)
@NATIVE_TRUE@
test_macho_DEPENDENCIES
=
libbacktrace_noformat.la
\
@NATIVE_TRUE@ macho.lo
test_macho_LINK
=
$(LIBTOOL)
$(AM_V_lt)
--tag
=
CC
$(AM_LIBTOOLFLAGS)
\
$(LIBTOOLFLAGS)
--mode
=
link
$(CCLD)
$(test_macho_CFLAGS)
\
$(CFLAGS)
$(AM_LDFLAGS)
$(LDFLAGS)
-o
$@
@NATIVE_TRUE@
am_test_pecoff_OBJECTS
=
\
@NATIVE_TRUE@
am_test_pecoff_OBJECTS
=
\
@NATIVE_TRUE@ test_pecoff-test_format.
$(OBJEXT)
\
@NATIVE_TRUE@ test_pecoff-test_format.
$(OBJEXT)
\
@NATIVE_TRUE@ test_pecoff-testlib.
$(OBJEXT)
@NATIVE_TRUE@ test_pecoff-testlib.
$(OBJEXT)
...
@@ -543,10 +559,10 @@ SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \
...
@@ -543,10 +559,10 @@ SOURCES = $(libbacktrace_la_SOURCES) $(EXTRA_libbacktrace_la_SOURCES) \
$(dwarf5_alloc_SOURCES)
$(edtest_SOURCES)
\
$(dwarf5_alloc_SOURCES)
$(edtest_SOURCES)
\
$(edtest_alloc_SOURCES)
$(stest_SOURCES)
\
$(edtest_alloc_SOURCES)
$(stest_SOURCES)
\
$(stest_alloc_SOURCES)
$(test_elf_32_SOURCES)
\
$(stest_alloc_SOURCES)
$(test_elf_32_SOURCES)
\
$(test_elf_64_SOURCES)
$(test_
pecoff
_SOURCES)
\
$(test_elf_64_SOURCES)
$(test_
macho
_SOURCES)
\
$(test_
unknown_SOURCES)
$(test_xcoff_32
_SOURCES)
\
$(test_
pecoff_SOURCES)
$(test_unknown
_SOURCES)
\
$(test_xcoff_
64_SOURCES)
$(ttest
_SOURCES)
\
$(test_xcoff_
32_SOURCES)
$(test_xcoff_64
_SOURCES)
\
$(ttest_alloc_SOURCES)
$(unittest_SOURCES)
\
$(ttest_
SOURCES)
$(ttest_
alloc_SOURCES)
$(unittest_SOURCES)
\
$(unittest_alloc_SOURCES)
$(ztest_SOURCES)
\
$(unittest_alloc_SOURCES)
$(ztest_SOURCES)
\
$(ztest_alloc_SOURCES)
$(ztest_alloc_SOURCES)
am__can_run_installinfo
=
\
am__can_run_installinfo
=
\
...
@@ -906,6 +922,7 @@ BACKTRACE_FILES = \
...
@@ -906,6 +922,7 @@ BACKTRACE_FILES = \
FORMAT_FILES
=
\
FORMAT_FILES
=
\
elf.c
\
elf.c
\
macho.c
\
pecoff.c
\
pecoff.c
\
unknown.c
\
unknown.c
\
xcoff.c
xcoff.c
...
@@ -932,10 +949,13 @@ libbacktrace_la_LIBADD = \
...
@@ -932,10 +949,13 @@ libbacktrace_la_LIBADD = \
libbacktrace_la_DEPENDENCIES
=
$(libbacktrace_la_LIBADD)
libbacktrace_la_DEPENDENCIES
=
$(libbacktrace_la_LIBADD)
# Add test to this variable, if you want it to be build and run.
# Add a test to this variable if you want it to be built and run.
BUILDTESTS
=
$(am__append_2)
$(am__append_9)
$(am__append_10)
\
BUILDTESTS
=
$(am__append_2)
$(am__append_10)
$(am__append_11)
\
$(am__append_15)
$(am__append_16)
$(am__append_17)
\
$(am__append_16)
$(am__append_17)
$(am__append_18)
\
$(am__append_19)
$(am__append_20)
$(am__append_21)
$(am__append_22)
# Add a file to this variable if you want it to be built for testing.
check_DATA
=
$(am__append_5)
$(am__append_19)
$(am__append_23)
# Flags to use when compiling test programs.
# Flags to use when compiling test programs.
libbacktrace_TEST_CFLAGS
=
$(EXTRA_FLAGS)
$(WARN_FLAGS)
-g
libbacktrace_TEST_CFLAGS
=
$(EXTRA_FLAGS)
$(WARN_FLAGS)
-g
...
@@ -959,6 +979,9 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
...
@@ -959,6 +979,9 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
@NATIVE_TRUE@
test_elf_64_SOURCES
=
test_format.c testlib.c
@NATIVE_TRUE@
test_elf_64_SOURCES
=
test_format.c testlib.c
@NATIVE_TRUE@
test_elf_64_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
@NATIVE_TRUE@
test_elf_64_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
@NATIVE_TRUE@
test_elf_64_LDADD
=
libbacktrace_noformat.la elf_64.lo
@NATIVE_TRUE@
test_elf_64_LDADD
=
libbacktrace_noformat.la elf_64.lo
@NATIVE_TRUE@
test_macho_SOURCES
=
test_format.c testlib.c
@NATIVE_TRUE@
test_macho_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
@NATIVE_TRUE@
test_macho_LDADD
=
libbacktrace_noformat.la macho.lo
@NATIVE_TRUE@
test_xcoff_32_SOURCES
=
test_format.c testlib.c
@NATIVE_TRUE@
test_xcoff_32_SOURCES
=
test_format.c testlib.c
@NATIVE_TRUE@
test_xcoff_32_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
@NATIVE_TRUE@
test_xcoff_32_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
@NATIVE_TRUE@
test_xcoff_32_LDADD
=
libbacktrace_noformat.la xcoff_32.lo
@NATIVE_TRUE@
test_xcoff_32_LDADD
=
libbacktrace_noformat.la xcoff_32.lo
...
@@ -1013,10 +1036,10 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
...
@@ -1013,10 +1036,10 @@ libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_SOURCES
=
ztest.c testlib.c
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_SOURCES
=
ztest.c testlib.c
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
-DSRCDIR
=
\"
$(srcdir)
\"
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_CFLAGS
=
$(libbacktrace_TEST_CFLAGS)
-DSRCDIR
=
\"
$(srcdir)
\"
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_LDADD
=
libbacktrace.la
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_LDADD
=
libbacktrace.la
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(am__append_1
3
)
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(am__append_1
4
)
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(CLOCK_GETTIME_LINK)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(CLOCK_GETTIME_LINK)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_LDADD
=
libbacktrace_alloc.la
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_LDADD
=
libbacktrace_alloc.la
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(am__append_1
4
)
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(am__append_1
5
)
\
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(CLOCK_GETTIME_LINK)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
$(CLOCK_GETTIME_LINK)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_SOURCES
=
$(ztest_SOURCES)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_SOURCES
=
$(ztest_SOURCES)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_CFLAGS
=
$(ztest_CFLAGS)
@HAVE_ELF_TRUE@@NATIVE_TRUE@
ztest_alloc_CFLAGS
=
$(ztest_CFLAGS)
...
@@ -1255,6 +1278,10 @@ test_elf_64$(EXEEXT): $(test_elf_64_OBJECTS) $(test_elf_64_DEPENDENCIES) $(EXTRA
...
@@ -1255,6 +1278,10 @@ test_elf_64$(EXEEXT): $(test_elf_64_OBJECTS) $(test_elf_64_DEPENDENCIES) $(EXTRA
@
rm
-f
test_elf_64
$(EXEEXT)
@
rm
-f
test_elf_64
$(EXEEXT)
$(AM_V_CCLD)$(test_elf_64_LINK)
$(test_elf_64_OBJECTS)
$(test_elf_64_LDADD)
$(LIBS)
$(AM_V_CCLD)$(test_elf_64_LINK)
$(test_elf_64_OBJECTS)
$(test_elf_64_LDADD)
$(LIBS)
test_macho$(EXEEXT)
:
$(test_macho_OBJECTS) $(test_macho_DEPENDENCIES) $(EXTRA_test_macho_DEPENDENCIES)
@
rm
-f
test_macho
$(EXEEXT)
$(AM_V_CCLD)$(test_macho_LINK)
$(test_macho_OBJECTS)
$(test_macho_LDADD)
$(LIBS)
test_pecoff$(EXEEXT)
:
$(test_pecoff_OBJECTS) $(test_pecoff_DEPENDENCIES) $(EXTRA_test_pecoff_DEPENDENCIES)
test_pecoff$(EXEEXT)
:
$(test_pecoff_OBJECTS) $(test_pecoff_DEPENDENCIES) $(EXTRA_test_pecoff_DEPENDENCIES)
@
rm
-f
test_pecoff
$(EXEEXT)
@
rm
-f
test_pecoff
$(EXEEXT)
$(AM_V_CCLD)$(test_pecoff_LINK)
$(test_pecoff_OBJECTS)
$(test_pecoff_LDADD)
$(LIBS)
$(AM_V_CCLD)$(test_pecoff_LINK)
$(test_pecoff_OBJECTS)
$(test_pecoff_LDADD)
$(LIBS)
...
@@ -1526,6 +1553,18 @@ test_elf_64-testlib.o: testlib.c
...
@@ -1526,6 +1553,18 @@ test_elf_64-testlib.o: testlib.c
test_elf_64-testlib.obj
:
testlib.c
test_elf_64-testlib.obj
:
testlib.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_elf_64_CFLAGS)
$(CFLAGS)
-c
-o
test_elf_64-testlib.obj
`
if
test
-f
'testlib.c'
;
then
$(CYGPATH_W)
'testlib.c'
;
else
$(CYGPATH_W)
'
$(srcdir)
/testlib.c'
;
fi
`
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_elf_64_CFLAGS)
$(CFLAGS)
-c
-o
test_elf_64-testlib.obj
`
if
test
-f
'testlib.c'
;
then
$(CYGPATH_W)
'testlib.c'
;
else
$(CYGPATH_W)
'
$(srcdir)
/testlib.c'
;
fi
`
test_macho-test_format.o
:
test_format.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_macho_CFLAGS)
$(CFLAGS)
-c
-o
test_macho-test_format.o
`
test
-f
'test_format.c'
||
echo
'
$(srcdir)
/'
`
test_format.c
test_macho-test_format.obj
:
test_format.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_macho_CFLAGS)
$(CFLAGS)
-c
-o
test_macho-test_format.obj
`
if
test
-f
'test_format.c'
;
then
$(CYGPATH_W)
'test_format.c'
;
else
$(CYGPATH_W)
'
$(srcdir)
/test_format.c'
;
fi
`
test_macho-testlib.o
:
testlib.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_macho_CFLAGS)
$(CFLAGS)
-c
-o
test_macho-testlib.o
`
test
-f
'testlib.c'
||
echo
'
$(srcdir)
/'
`
testlib.c
test_macho-testlib.obj
:
testlib.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_macho_CFLAGS)
$(CFLAGS)
-c
-o
test_macho-testlib.obj
`
if
test
-f
'testlib.c'
;
then
$(CYGPATH_W)
'testlib.c'
;
else
$(CYGPATH_W)
'
$(srcdir)
/testlib.c'
;
fi
`
test_pecoff-test_format.o
:
test_format.c
test_pecoff-test_format.o
:
test_format.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_pecoff_CFLAGS)
$(CFLAGS)
-c
-o
test_pecoff-test_format.o
`
test
-f
'test_format.c'
||
echo
'
$(srcdir)
/'
`
test_format.c
$(AM_V_CC)$(CC)
$(DEFS)
$(DEFAULT_INCLUDES)
$(INCLUDES)
$(AM_CPPFLAGS)
$(CPPFLAGS)
$(test_pecoff_CFLAGS)
$(CFLAGS)
-c
-o
test_pecoff-test_format.o
`
test
-f
'test_format.c'
||
echo
'
$(srcdir)
/'
`
test_format.c
...
@@ -1865,7 +1904,7 @@ check-TESTS:
...
@@ -1865,7 +1904,7 @@ check-TESTS:
log_list
=
`
echo
$$
log_list
`
;
trs_list
=
`
echo
$$
trs_list
`
;
\
log_list
=
`
echo
$$
log_list
`
;
trs_list
=
`
echo
$$
trs_list
`
;
\
$(MAKE)
$(AM_MAKEFLAGS)
$(TEST_SUITE_LOG)
TEST_LOGS
=
"
$$
log_list"
;
\
$(MAKE)
$(AM_MAKEFLAGS)
$(TEST_SUITE_LOG)
TEST_LOGS
=
"
$$
log_list"
;
\
exit
$$
?
;
exit
$$
?
;
recheck
:
all $(check_LTLIBRARIES) $(check_PROGRAMS)
recheck
:
all $(check_LTLIBRARIES) $(check_PROGRAMS)
$(check_DATA)
@
test
-z
"
$(TEST_SUITE_LOG)
"
||
rm
-f
$(TEST_SUITE_LOG)
@
test
-z
"
$(TEST_SUITE_LOG)
"
||
rm
-f
$(TEST_SUITE_LOG)
@
set
+e
;
$(am__set_TESTS_bases)
;
\
@
set
+e
;
$(am__set_TESTS_bases)
;
\
bases
=
`
for
i
in
$$
bases
;
do
echo
$$
i
;
done
\
bases
=
`
for
i
in
$$
bases
;
do
echo
$$
i
;
done
\
...
@@ -1932,6 +1971,13 @@ test_elf_64.log: test_elf_64$(EXEEXT)
...
@@ -1932,6 +1971,13 @@ test_elf_64.log: test_elf_64$(EXEEXT)
--log-file
$$
b.log
--trs-file
$$
b.trs
\
--log-file
$$
b.log
--trs-file
$$
b.trs
\
$(am__common_driver_flags)
$(AM_LOG_DRIVER_FLAGS)
$(LOG_DRIVER_FLAGS)
--
$(LOG_COMPILE)
\
$(am__common_driver_flags)
$(AM_LOG_DRIVER_FLAGS)
$(LOG_DRIVER_FLAGS)
--
$(LOG_COMPILE)
\
"
$$
tst"
$(AM_TESTS_FD_REDIRECT)
"
$$
tst"
$(AM_TESTS_FD_REDIRECT)
test_macho.log
:
test_macho$(EXEEXT)
@
p
=
'test_macho
$(EXEEXT)
'
;
\
b
=
'test_macho'
;
\
$(am__check_pre)
$(LOG_DRIVER)
--test-name
"
$$
f"
\
--log-file
$$
b.log
--trs-file
$$
b.trs
\
$(am__common_driver_flags)
$(AM_LOG_DRIVER_FLAGS)
$(LOG_DRIVER_FLAGS)
--
$(LOG_COMPILE)
\
"
$$
tst"
$(AM_TESTS_FD_REDIRECT)
test_xcoff_32.log
:
test_xcoff_32$(EXEEXT)
test_xcoff_32.log
:
test_xcoff_32$(EXEEXT)
@
p
=
'test_xcoff_32
$(EXEEXT)
'
;
\
@
p
=
'test_xcoff_32
$(EXEEXT)
'
;
\
b
=
'test_xcoff_32'
;
\
b
=
'test_xcoff_32'
;
\
...
@@ -2108,7 +2154,8 @@ dwarf5_alloc.log: dwarf5_alloc$(EXEEXT)
...
@@ -2108,7 +2154,8 @@ dwarf5_alloc.log: dwarf5_alloc$(EXEEXT)
@am__EXEEXT_TRUE@
$(am__common_driver_flags)
$(AM_TEST_LOG_DRIVER_FLAGS)
$(TEST_LOG_DRIVER_FLAGS)
--
$(TEST_LOG_COMPILE)
\
@am__EXEEXT_TRUE@
$(am__common_driver_flags)
$(AM_TEST_LOG_DRIVER_FLAGS)
$(TEST_LOG_DRIVER_FLAGS)
--
$(TEST_LOG_COMPILE)
\
@am__EXEEXT_TRUE@
"
$$
tst"
$(AM_TESTS_FD_REDIRECT)
@am__EXEEXT_TRUE@
"
$$
tst"
$(AM_TESTS_FD_REDIRECT)
check-am
:
all-am
check-am
:
all-am
$(MAKE)
$(AM_MAKEFLAGS)
$(check_LTLIBRARIES)
$(check_PROGRAMS)
$(MAKE)
$(AM_MAKEFLAGS)
$(check_LTLIBRARIES)
$(check_PROGRAMS)
\
$(check_DATA)
$(MAKE)
$(AM_MAKEFLAGS)
check-TESTS
$(MAKE)
$(AM_MAKEFLAGS)
check-TESTS
check
:
check-am
check
:
check-am
all-am
:
Makefile $(LTLIBRARIES) $(HEADERS) config.h
all-am
:
Makefile $(LTLIBRARIES) $(HEADERS) config.h
...
@@ -2245,6 +2292,9 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
...
@@ -2245,6 +2292,9 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES
.PRECIOUS
:
Makefile
.PRECIOUS
:
Makefile
@HAVE_DSYMUTIL_TRUE@%.dSYM
:
%
@HAVE_DSYMUTIL_TRUE@
$(DSYMUTIL)
$<
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@elf_for_test.c
:
elf.c
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@elf_for_test.c
:
elf.c
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
SEARCH
=
'^#define SYSTEM_BUILD_ID_DIR.*$$'
;
\
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
SEARCH
=
'^#define SYSTEM_BUILD_ID_DIR.*$$'
;
\
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
REPLACE
=
"#define SYSTEM_BUILD_ID_DIR
\"
$(TEST_BUILD_ID_DIR)
\"
"
;
\
@HAVE_ELF_TRUE@@HAVE_OBJCOPY_DEBUGLINK_TRUE@@NATIVE_TRUE@
REPLACE
=
"#define SYSTEM_BUILD_ID_DIR
\"
$(TEST_BUILD_ID_DIR)
\"
"
;
\
...
@@ -2320,6 +2370,7 @@ btest.lo: filenames.h backtrace.h backtrace-supported.h
...
@@ -2320,6 +2370,7 @@ btest.lo: filenames.h backtrace.h backtrace-supported.h
dwarf.lo
:
config.h filenames.h backtrace.h internal.h
dwarf.lo
:
config.h filenames.h backtrace.h internal.h
elf.lo
:
config.h backtrace.h internal.h
elf.lo
:
config.h backtrace.h internal.h
fileline.lo
:
config.h backtrace.h internal.h
fileline.lo
:
config.h backtrace.h internal.h
macho.lo
:
config.h backtrace.h internal.h
mmap.lo
:
config.h backtrace.h internal.h
mmap.lo
:
config.h backtrace.h internal.h
mmapio.lo
:
config.h backtrace.h internal.h
mmapio.lo
:
config.h backtrace.h internal.h
nounwind.lo
:
config.h internal.h
nounwind.lo
:
config.h internal.h
...
...
config.h.in
View file @
4e548e73
...
@@ -51,6 +51,9 @@
...
@@ -51,6 +51,9 @@
/* Define to 1 if you have the `lstat' function. */
/* Define to 1 if you have the `lstat' function. */
#undef HAVE_LSTAT
#undef HAVE_LSTAT
/* Define to 1 if you have the <mach-o/dyld.h> header file. */
#undef HAVE_MACH_O_DYLD_H
/* Define to 1 if you have the <memory.h> header file. */
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
#undef HAVE_MEMORY_H
...
...
configure
View file @
4e548e73
...
@@ -635,6 +635,8 @@ LTLIBOBJS
...
@@ -635,6 +635,8 @@ LTLIBOBJS
LIBOBJS
LIBOBJS
NATIVE_FALSE
NATIVE_FALSE
NATIVE_TRUE
NATIVE_TRUE
HAVE_DSYMUTIL_FALSE
HAVE_DSYMUTIL_TRUE
HAVE_OBJCOPY_DEBUGLINK_FALSE
HAVE_OBJCOPY_DEBUGLINK_FALSE
HAVE_OBJCOPY_DEBUGLINK_TRUE
HAVE_OBJCOPY_DEBUGLINK_TRUE
READELF
READELF
...
@@ -799,7 +801,8 @@ LDFLAGS
...
@@ -799,7 +801,8 @@ LDFLAGS
LIBS
LIBS
CPPFLAGS
CPPFLAGS
CPP
CPP
OBJCOPY'
OBJCOPY
DSYMUTIL'
# Initialize some variables set by options.
# Initialize some variables set by options.
...
@@ -1452,6 +1455,7 @@ Some influential environment variables:
...
@@ -1452,6 +1455,7 @@ Some influential environment variables:
you have headers in a nonstandard directory <include dir>
you have headers in a nonstandard directory <include dir>
CPP C preprocessor
CPP C preprocessor
OBJCOPY location of objcopy
OBJCOPY location of objcopy
DSYMUTIL location of dsymutil
Use these variables to override the choices made by `configure' or to help
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
it to find libraries and programs with nonstandard names/locations.
...
@@ -11265,7 +11269,7 @@ else
...
@@ -11265,7 +11269,7 @@ else
lt_dlunknown
=
0
;
lt_dlno_uscore
=
1
;
lt_dlneed_uscore
=
2
lt_dlunknown
=
0
;
lt_dlno_uscore
=
1
;
lt_dlneed_uscore
=
2
lt_status
=
$lt_dlunknown
lt_status
=
$lt_dlunknown
cat
>
conftest.
$ac_ext
<<
_LT_EOF
cat
>
conftest.
$ac_ext
<<
_LT_EOF
#line 112
68
"configure"
#line 112
72
"configure"
#include "confdefs.h"
#include "confdefs.h"
#if HAVE_DLFCN_H
#if HAVE_DLFCN_H
...
@@ -11371,7 +11375,7 @@ else
...
@@ -11371,7 +11375,7 @@ else
lt_dlunknown
=
0
;
lt_dlno_uscore
=
1
;
lt_dlneed_uscore
=
2
lt_dlunknown
=
0
;
lt_dlno_uscore
=
1
;
lt_dlneed_uscore
=
2
lt_status
=
$lt_dlunknown
lt_status
=
$lt_dlunknown
cat
>
conftest.
$ac_ext
<<
_LT_EOF
cat
>
conftest.
$ac_ext
<<
_LT_EOF
#line 1137
4
"configure"
#line 1137
8
"configure"
#include "confdefs.h"
#include "confdefs.h"
#if HAVE_DLFCN_H
#if HAVE_DLFCN_H
...
@@ -12176,6 +12180,7 @@ FORMAT_FILE=
...
@@ -12176,6 +12180,7 @@ FORMAT_FILE=
backtrace_supports_data
=
yes
backtrace_supports_data
=
yes
case
"
$libbacktrace_cv_sys_filetype
"
in
case
"
$libbacktrace_cv_sys_filetype
"
in
elf
*
)
FORMAT_FILE
=
"elf.lo"
;;
elf
*
)
FORMAT_FILE
=
"elf.lo"
;;
macho
)
FORMAT_FILE
=
"macho.lo"
;;
pecoff
)
FORMAT_FILE
=
"pecoff.lo"
pecoff
)
FORMAT_FILE
=
"pecoff.lo"
backtrace_supports_data
=
no
backtrace_supports_data
=
no
;;
;;
...
@@ -12355,6 +12360,20 @@ $as_echo "#define HAVE_DL_ITERATE_PHDR 1" >>confdefs.h
...
@@ -12355,6 +12360,20 @@ $as_echo "#define HAVE_DL_ITERATE_PHDR 1" >>confdefs.h
fi
fi
# Check for header file for Mach-O image functions.
for
ac_header
in
mach-o/dyld.h
do
:
ac_fn_c_check_header_mongrel
"
$LINENO
"
"mach-o/dyld.h"
"ac_cv_header_mach_o_dyld_h"
"
$ac_includes_default
"
if
test
"x
$ac_cv_header_mach_o_dyld_h
"
=
xyes
;
then
:
cat
>>
confdefs.h
<<
_ACEOF
#define HAVE_MACH_O_DYLD_H 1
_ACEOF
fi
done
# Check for loadquery.
# Check for loadquery.
for
ac_header
in
sys/ldr.h
for
ac_header
in
sys/ldr.h
do
:
do
:
...
@@ -12840,6 +12859,8 @@ if ${libbacktrace_cv_objcopy_debuglink+:} false; then :
...
@@ -12840,6 +12859,8 @@ if ${libbacktrace_cv_objcopy_debuglink+:} false; then :
else
else
if
test
-n
"
${
with_target_subdir
}
"
;
then
if
test
-n
"
${
with_target_subdir
}
"
;
then
libbacktrace_cv_objcopy_debuglink
=
no
libbacktrace_cv_objcopy_debuglink
=
no
elif
!
test
-n
"
${
OBJCOPY
}
"
;
then
libbacktrace_cv_objcopy_debuglink
=
no
elif
${
OBJCOPY
}
--add-gnu-debuglink
=
x /bin/ls /tmp/ls
$$
;
then
elif
${
OBJCOPY
}
--add-gnu-debuglink
=
x /bin/ls /tmp/ls
$$
;
then
rm
-f
/tmp/ls
$$
rm
-f
/tmp/ls
$$
libbacktrace_cv_objcopy_debuglink
=
yes
libbacktrace_cv_objcopy_debuglink
=
yes
...
@@ -12858,6 +12879,53 @@ else
...
@@ -12858,6 +12879,53 @@ else
fi
fi
# Extract the first word of "dsymutil", so it can be a program name with args.
set
dummy dsymutil
;
ac_word
=
$2
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking for
$ac_word
"
>
&5
$as_echo_n
"checking for
$ac_word
... "
>
&6
;
}
if
${
ac_cv_prog_DSYMUTIL
+
:
}
false
;
then
:
$as_echo_n
"(cached) "
>
&6
else
if
test
-n
"
$DSYMUTIL
"
;
then
ac_cv_prog_DSYMUTIL
=
"
$DSYMUTIL
"
# Let the user override the test.
else
as_save_IFS
=
$IFS
;
IFS
=
$PATH_SEPARATOR
for
as_dir
in
$PATH
do
IFS
=
$as_save_IFS
test
-z
"
$as_dir
"
&&
as_dir
=
.
for
ac_exec_ext
in
''
$ac_executable_extensions
;
do
if
as_fn_executable_p
"
$as_dir
/
$ac_word$ac_exec_ext
"
;
then
ac_cv_prog_DSYMUTIL
=
"dsymutil"
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: found
$as_dir
/
$ac_word$ac_exec_ext
"
>
&5
break
2
fi
done
done
IFS
=
$as_save_IFS
fi
fi
DSYMUTIL
=
$ac_cv_prog_DSYMUTIL
if
test
-n
"
$DSYMUTIL
"
;
then
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result:
$DSYMUTIL
"
>
&5
$as_echo
"
$DSYMUTIL
"
>
&6
;
}
else
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: result: no"
>
&5
$as_echo
"no"
>
&6
;
}
fi
if
test
-n
"
${
DSYMUTIL
}
"
;
then
HAVE_DSYMUTIL_TRUE
=
HAVE_DSYMUTIL_FALSE
=
'#'
else
HAVE_DSYMUTIL_TRUE
=
'#'
HAVE_DSYMUTIL_FALSE
=
fi
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking whether tests can run"
>
&5
{
$as_echo
"
$as_me
:
${
as_lineno
-
$LINENO
}
: checking whether tests can run"
>
&5
$as_echo_n
"checking whether tests can run... "
>
&6
;
}
$as_echo_n
"checking whether tests can run... "
>
&6
;
}
if
${
libbacktrace_cv_sys_native
+
:
}
false
;
then
:
if
${
libbacktrace_cv_sys_native
+
:
}
false
;
then
:
...
@@ -13070,6 +13138,10 @@ if test -z "${HAVE_OBJCOPY_DEBUGLINK_TRUE}" && test -z "${HAVE_OBJCOPY_DEBUGLINK
...
@@ -13070,6 +13138,10 @@ if test -z "${HAVE_OBJCOPY_DEBUGLINK_TRUE}" && test -z "${HAVE_OBJCOPY_DEBUGLINK
as_fn_error
$?
"conditional
\"
HAVE_OBJCOPY_DEBUGLINK
\"
was never defined.
as_fn_error
$?
"conditional
\"
HAVE_OBJCOPY_DEBUGLINK
\"
was never defined.
Usually this means the macro was only invoked conditionally."
"
$LINENO
"
5
Usually this means the macro was only invoked conditionally."
"
$LINENO
"
5
fi
fi
if
test
-z
"
${
HAVE_DSYMUTIL_TRUE
}
"
&&
test
-z
"
${
HAVE_DSYMUTIL_FALSE
}
"
;
then
as_fn_error
$?
"conditional
\"
HAVE_DSYMUTIL
\"
was never defined.
Usually this means the macro was only invoked conditionally."
"
$LINENO
"
5
fi
if
test
-z
"
${
NATIVE_TRUE
}
"
&&
test
-z
"
${
NATIVE_FALSE
}
"
;
then
if
test
-z
"
${
NATIVE_TRUE
}
"
&&
test
-z
"
${
NATIVE_FALSE
}
"
;
then
as_fn_error
$?
"conditional
\"
NATIVE
\"
was never defined.
as_fn_error
$?
"conditional
\"
NATIVE
\"
was never defined.
Usually this means the macro was only invoked conditionally."
"
$LINENO
"
5
Usually this means the macro was only invoked conditionally."
"
$LINENO
"
5
...
...
configure.ac
View file @
4e548e73
...
@@ -238,6 +238,7 @@ FORMAT_FILE=
...
@@ -238,6 +238,7 @@ FORMAT_FILE=
backtrace_supports_data=yes
backtrace_supports_data=yes
case "$libbacktrace_cv_sys_filetype" in
case "$libbacktrace_cv_sys_filetype" in
elf*) FORMAT_FILE="elf.lo" ;;
elf*) FORMAT_FILE="elf.lo" ;;
macho) FORMAT_FILE="macho.lo" ;;
pecoff) FORMAT_FILE="pecoff.lo"
pecoff) FORMAT_FILE="pecoff.lo"
backtrace_supports_data=no
backtrace_supports_data=no
;;
;;
...
@@ -346,6 +347,9 @@ if test "$have_dl_iterate_phdr" = "yes"; then
...
@@ -346,6 +347,9 @@ if test "$have_dl_iterate_phdr" = "yes"; then
AC_DEFINE(HAVE_DL_ITERATE_PHDR, 1, [Define if dl_iterate_phdr is available.])
AC_DEFINE(HAVE_DL_ITERATE_PHDR, 1, [Define if dl_iterate_phdr is available.])
fi
fi
# Check for header file for Mach-O image functions.
AC_CHECK_HEADERS(mach-o/dyld.h)
# Check for loadquery.
# Check for loadquery.
AC_CHECK_HEADERS(sys/ldr.h)
AC_CHECK_HEADERS(sys/ldr.h)
if test "$ac_cv_header_sys_ldr_h" = "no"; then
if test "$ac_cv_header_sys_ldr_h" = "no"; then
...
@@ -490,6 +494,8 @@ AC_CACHE_CHECK([whether objcopy supports debuglink],
...
@@ -490,6 +494,8 @@ AC_CACHE_CHECK([whether objcopy supports debuglink],
[libbacktrace_cv_objcopy_debuglink],
[libbacktrace_cv_objcopy_debuglink],
[if test -n "${with_target_subdir}"; then
[if test -n "${with_target_subdir}"; then
libbacktrace_cv_objcopy_debuglink=no
libbacktrace_cv_objcopy_debuglink=no
elif ! test -n "${OBJCOPY}"; then
libbacktrace_cv_objcopy_debuglink=no
elif ${OBJCOPY} --add-gnu-debuglink=x /bin/ls /tmp/ls$$; then
elif ${OBJCOPY} --add-gnu-debuglink=x /bin/ls /tmp/ls$$; then
rm -f /tmp/ls$$
rm -f /tmp/ls$$
libbacktrace_cv_objcopy_debuglink=yes
libbacktrace_cv_objcopy_debuglink=yes
...
@@ -498,6 +504,10 @@ else
...
@@ -498,6 +504,10 @@ else
fi])
fi])
AM_CONDITIONAL(HAVE_OBJCOPY_DEBUGLINK, test "$libbacktrace_cv_objcopy_debuglink" = yes)
AM_CONDITIONAL(HAVE_OBJCOPY_DEBUGLINK, test "$libbacktrace_cv_objcopy_debuglink" = yes)
AC_ARG_VAR(DSYMUTIL, [location of dsymutil])
AC_CHECK_PROG(DSYMUTIL, dsymutil, dsymutil)
AM_CONDITIONAL(HAVE_DSYMUTIL, test -n "${DSYMUTIL}")
AC_CACHE_CHECK([whether tests can run],
AC_CACHE_CHECK([whether tests can run],
[libbacktrace_cv_sys_native],
[libbacktrace_cv_sys_native],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
...
...
filetype.awk
View file @
4e548e73
# An awk script to determine the type of a file.
# An awk script to determine the type of a file.
/
\
177
ELF
\
001
/
{
if
(
NR
==
1
)
{
print
"elf32"
;
exit
}
}
/
\
177
ELF
\
001
/
{
if
(
NR
==
1
)
{
print
"elf32"
;
exit
}
}
/
\1
77ELF
\0
02/
{
if
(
NR
==
1
)
{
print
"elf64"
;
exit
}
}
/
\1
77ELF
\0
02/
{
if
(
NR
==
1
)
{
print
"elf64"
;
exit
}
}
/
\1
14
\0
01/
{
if
(
NR
==
1
)
{
print
"pecoff"
;
exit
}
}
/
\1
14
\0
01/
{
if
(
NR
==
1
)
{
print
"pecoff"
;
exit
}
}
/
\1
44
\2
06/
{
if
(
NR
==
1
)
{
print
"pecoff"
;
exit
}
}
/
\1
44
\2
06/
{
if
(
NR
==
1
)
{
print
"pecoff"
;
exit
}
}
/
\0
01
\3
37/
{
if
(
NR
==
1
)
{
print
"xcoff32"
;
exit
}
}
/
\0
01
\3
37/
{
if
(
NR
==
1
)
{
print
"xcoff32"
;
exit
}
}
/
\0
01
\3
67/
{
if
(
NR
==
1
)
{
print
"xcoff64"
;
exit
}
}
/
\0
01
\3
67/
{
if
(
NR
==
1
)
{
print
"xcoff64"
;
exit
}
}
/
\3
76
\3
55
\3
72
\3
16/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
/
\3
16
\3
72
\3
55
\3
76/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
/
\3
76
\3
55
\3
72
\3
17/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
/
\3
17
\3
72
\3
55
\3
76/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
/
\3
12
\3
76
\2
72
\2
76/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
/
\2
76
\2
72
\3
76
\3
12/
{
if
(
NR
==
1
)
{
print
"macho"
;
exit
}
}
macho.c
0 → 100644
View file @
4e548e73
/* elf.c -- Get debug data from a Mach-O file for backtraces.
Copyright (C) 2020 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) 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.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */
#include "config.h"
#include <sys/types.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_MACH_O_DYLD_H
#include <mach-o/dyld.h>
#endif
#include "backtrace.h"
#include "internal.h"
/* Mach-O file header for a 32-bit executable. */
struct
macho_header_32
{
uint32_t
magic
;
/* Magic number (MACH_O_MAGIC_32) */
uint32_t
cputype
;
/* CPU type */
uint32_t
cpusubtype
;
/* CPU subtype */
uint32_t
filetype
;
/* Type of file (object, executable) */
uint32_t
ncmds
;
/* Number of load commands */
uint32_t
sizeofcmds
;
/* Total size of load commands */
uint32_t
flags
;
/* Flags for special features */
};
/* Mach-O file header for a 64-bit executable. */
struct
macho_header_64
{
uint32_t
magic
;
/* Magic number (MACH_O_MAGIC_64) */
uint32_t
cputype
;
/* CPU type */
uint32_t
cpusubtype
;
/* CPU subtype */
uint32_t
filetype
;
/* Type of file (object, executable) */
uint32_t
ncmds
;
/* Number of load commands */
uint32_t
sizeofcmds
;
/* Total size of load commands */
uint32_t
flags
;
/* Flags for special features */
uint32_t
reserved
;
/* Reserved */
};
/* Mach-O file header for a fat executable. */
struct
macho_header_fat
{
uint32_t
magic
;
/* Magic number (MACH_O_MH_MAGIC_FAT) */
uint32_t
nfat_arch
;
/* Number of components */
};
/* Values for the header magic field. */
#define MACH_O_MH_MAGIC_32 0xfeedface
#define MACH_O_MH_MAGIC_64 0xfeedfacf
#define MACH_O_MH_MAGIC_FAT 0xcafebabe
#define MACH_O_MH_CIGAM_FAT 0xbebafeca
/* Value for the header filetype field. */
#define MACH_O_MH_EXECUTE 0x02
#define MACH_O_MH_DYLIB 0x06
#define MACH_O_MH_DSYM 0x0a
/* A component of a fat file. A fat file starts with a
macho_header_fat followed by nfat_arch instances of this
struct. */
struct
macho_fat_arch
{
uint32_t
cputype
;
/* CPU type */
uint32_t
cpusubtype
;
/* CPU subtype */
uint32_t
offset
;
/* File offset of this entry */
uint32_t
size
;
/* Size of this entry */
uint32_t
align
;
/* Alignment of this entry */
};
/* Values for the fat_arch cputype field (and the header cputype
field). */
#define MACH_O_CPU_ARCH_ABI64 0x01000000
#define MACH_O_CPU_TYPE_X86 7
#define MACH_O_CPU_TYPE_ARM 12
#define MACH_O_CPU_TYPE_X86_64 (MACH_O_CPU_TYPE_X86 | MACH_O_CPU_ARCH_ABI64)
#define MACH_O_CPU_TYPE_ARM64 (MACH_O_CPU_TYPE_ARM | MACH_O_CPU_ARCH_ABI64)
/* The header of a load command. */
struct
macho_load_command
{
uint32_t
cmd
;
/* The type of load command */
uint32_t
cmdsize
;
/* Size in bytes of the entire command */
};
/* Values for the load_command cmd field. */
#define MACH_O_LC_SEGMENT 0x01
#define MACH_O_LC_SYMTAB 0x02
#define MACH_O_LC_SEGMENT_64 0x19
#define MACH_O_LC_UUID 0x1b
/* The length of a section of segment name. */
#define MACH_O_NAMELEN (16)
/* LC_SEGMENT load command. */
struct
macho_segment_command
{
uint32_t
cmd
;
/* The type of load command (LC_SEGMENT) */
uint32_t
cmdsize
;
/* Size in bytes of the entire command */
char
segname
[
MACH_O_NAMELEN
];
/* Segment name */
uint32_t
vmaddr
;
/* Virtual memory address */
uint32_t
vmsize
;
/* Virtual memory size */
uint32_t
fileoff
;
/* Offset of data to be mapped */
uint32_t
filesize
;
/* Size of data in file */
uint32_t
maxprot
;
/* Maximum permitted virtual protection */
uint32_t
initprot
;
/* Initial virtual memory protection */
uint32_t
nsects
;
/* Number of sections in this segment */
uint32_t
flags
;
/* Flags */
};
/* LC_SEGMENT_64 load command. */
struct
macho_segment_64_command
{
uint32_t
cmd
;
/* The type of load command (LC_SEGMENT) */
uint32_t
cmdsize
;
/* Size in bytes of the entire command */
char
segname
[
MACH_O_NAMELEN
];
/* Segment name */
uint64_t
vmaddr
;
/* Virtual memory address */
uint64_t
vmsize
;
/* Virtual memory size */
uint64_t
fileoff
;
/* Offset of data to be mapped */
uint64_t
filesize
;
/* Size of data in file */
uint32_t
maxprot
;
/* Maximum permitted virtual protection */
uint32_t
initprot
;
/* Initial virtual memory protection */
uint32_t
nsects
;
/* Number of sections in this segment */
uint32_t
flags
;
/* Flags */
};
/* LC_SYMTAB load command. */
struct
macho_symtab_command
{
uint32_t
cmd
;
/* The type of load command (LC_SEGMENT) */
uint32_t
cmdsize
;
/* Size in bytes of the entire command */
uint32_t
symoff
;
/* File offset of symbol table */
uint32_t
nsyms
;
/* Number of symbols */
uint32_t
stroff
;
/* File offset of string table */
uint32_t
strsize
;
/* String table size */
};
/* The length of a Mach-O uuid. */
#define MACH_O_UUID_LEN (16)
/* LC_UUID load command. */
struct
macho_uuid_command
{
uint32_t
cmd
;
/* Type of load command (LC_UUID) */
uint32_t
cmdsize
;
/* Size in bytes of command */
unsigned
char
uuid
[
MACH_O_UUID_LEN
];
/* UUID */
};
/* 32-bit section header within a LC_SEGMENT segment. */
struct
macho_section
{
char
sectname
[
MACH_O_NAMELEN
];
/* Section name */
char
segment
[
MACH_O_NAMELEN
];
/* Segment of this section */
uint32_t
addr
;
/* Address in memory */
uint32_t
size
;
/* Section size */
uint32_t
offset
;
/* File offset */
uint32_t
align
;
/* Log2 of section alignment */
uint32_t
reloff
;
/* File offset of relocations */
uint32_t
nreloc
;
/* Number of relocs for this section */
uint32_t
flags
;
/* Flags */
uint32_t
reserved1
;
uint32_t
reserved2
;
};
/* 64-bit section header within a LC_SEGMENT_64 segment. */
struct
macho_section_64
{
char
sectname
[
MACH_O_NAMELEN
];
/* Section name */
char
segment
[
MACH_O_NAMELEN
];
/* Segment of this section */
uint64_t
addr
;
/* Address in memory */
uint64_t
size
;
/* Section size */
uint32_t
offset
;
/* File offset */
uint32_t
align
;
/* Log2 of section alignment */
uint32_t
reloff
;
/* File offset of section relocations */
uint32_t
nreloc
;
/* Number of relocs for this section */
uint32_t
flags
;
/* Flags */
uint32_t
reserved1
;
uint32_t
reserved2
;
uint32_t
reserved3
;
};
/* 32-bit symbol data. */
struct
macho_nlist
{
uint32_t
n_strx
;
/* Index of name in string table */
uint8_t
n_type
;
/* Type flag */
uint8_t
n_sect
;
/* Section number */
uint16_t
n_desc
;
/* Stabs description field */
uint32_t
n_value
;
/* Value */
};
/* 64-bit symbol data. */
struct
macho_nlist_64
{
uint32_t
n_strx
;
/* Index of name in string table */
uint8_t
n_type
;
/* Type flag */
uint8_t
n_sect
;
/* Section number */
uint16_t
n_desc
;
/* Stabs description field */
uint64_t
n_value
;
/* Value */
};
/* Value found in nlist n_type field. */
#define MACH_O_N_EXT 0x01
/* Extern symbol */
#define MACH_O_N_ABS 0x02
/* Absolute symbol */
#define MACH_O_N_SECT 0x0e
/* Defined in section */
#define MACH_O_N_TYPE 0x0e
/* Mask for type bits */
#define MACH_O_N_STAB 0xe0
/* Stabs debugging symbol */
/* Information we keep for a Mach-O symbol. */
struct
macho_symbol
{
const
char
*
name
;
/* Symbol name */
uintptr_t
address
;
/* Symbol address */
};
/* Information to pass to macho_syminfo. */
struct
macho_syminfo_data
{
struct
macho_syminfo_data
*
next
;
/* Next module */
struct
macho_symbol
*
symbols
;
/* Symbols sorted by address */
size_t
count
;
/* Number of symbols */
};
/* Names of sections, indexed by enum dwarf_section in internal.h. */
static
const
char
*
const
dwarf_section_names
[
DEBUG_MAX
]
=
{
"__debug_info"
,
"__debug_line"
,
"__debug_abbrev"
,
"__debug_ranges"
,
"__debug_str"
,
""
,
/* DEBUG_ADDR */
"__debug_str_offs"
,
""
,
/* DEBUG_LINE_STR */
"__debug_rnglists"
};
/* Forward declaration. */
static
int
macho_add
(
struct
backtrace_state
*
,
const
char
*
,
int
,
off_t
,
const
unsigned
char
*
,
uintptr_t
,
int
,
backtrace_error_callback
,
void
*
,
fileline
*
,
int
*
);
/* A dummy callback function used when we can't find any debug info. */
static
int
macho_nodebug
(
struct
backtrace_state
*
state
ATTRIBUTE_UNUSED
,
uintptr_t
pc
ATTRIBUTE_UNUSED
,
backtrace_full_callback
callback
ATTRIBUTE_UNUSED
,
backtrace_error_callback
error_callback
,
void
*
data
)
{
error_callback
(
data
,
"no debug info in Mach-O executable"
,
-
1
);
return
0
;
}
/* A dummy callback function used when we can't find a symbol
table. */
static
void
macho_nosyms
(
struct
backtrace_state
*
state
ATTRIBUTE_UNUSED
,
uintptr_t
addr
ATTRIBUTE_UNUSED
,
backtrace_syminfo_callback
callback
ATTRIBUTE_UNUSED
,
backtrace_error_callback
error_callback
,
void
*
data
)
{
error_callback
(
data
,
"no symbol table in Mach-O executable"
,
-
1
);
}
/* Add a single DWARF section to DWARF_SECTIONS, if we need the
section. Returns 1 on success, 0 on failure. */
static
int
macho_add_dwarf_section
(
struct
backtrace_state
*
state
,
int
descriptor
,
const
char
*
sectname
,
uint32_t
offset
,
uint64_t
size
,
backtrace_error_callback
error_callback
,
void
*
data
,
struct
dwarf_sections
*
dwarf_sections
)
{
int
i
;
for
(
i
=
0
;
i
<
(
int
)
DEBUG_MAX
;
++
i
)
{
if
(
dwarf_section_names
[
i
][
0
]
!=
'\0'
&&
strncmp
(
sectname
,
dwarf_section_names
[
i
],
MACH_O_NAMELEN
)
==
0
)
{
struct
backtrace_view
section_view
;
/* FIXME: Perhaps it would be better to try to use a single
view to read all the DWARF data, as we try to do for
ELF. */
if
(
!
backtrace_get_view
(
state
,
descriptor
,
offset
,
size
,
error_callback
,
data
,
&
section_view
))
return
0
;
dwarf_sections
->
data
[
i
]
=
(
const
unsigned
char
*
)
section_view
.
data
;
dwarf_sections
->
size
[
i
]
=
size
;
break
;
}
}
return
1
;
}
/* Collect DWARF sections from a DWARF segment. Returns 1 on success,
0 on failure. */
static
int
macho_add_dwarf_segment
(
struct
backtrace_state
*
state
,
int
descriptor
,
off_t
offset
,
unsigned
int
cmd
,
const
char
*
psecs
,
size_t
sizesecs
,
unsigned
int
nsects
,
backtrace_error_callback
error_callback
,
void
*
data
,
struct
dwarf_sections
*
dwarf_sections
)
{
size_t
sec_header_size
;
size_t
secoffset
;
unsigned
int
i
;
switch
(
cmd
)
{
case
MACH_O_LC_SEGMENT
:
sec_header_size
=
sizeof
(
struct
macho_section
);
break
;
case
MACH_O_LC_SEGMENT_64
:
sec_header_size
=
sizeof
(
struct
macho_section_64
);
break
;
default:
abort
();
}
secoffset
=
0
;
for
(
i
=
0
;
i
<
nsects
;
++
i
)
{
if
(
secoffset
+
sec_header_size
>
sizesecs
)
{
error_callback
(
data
,
"section overflow withing segment"
,
0
);
return
0
;
}
switch
(
cmd
)
{
case
MACH_O_LC_SEGMENT
:
{
struct
macho_section
section
;
memcpy
(
&
section
,
psecs
+
secoffset
,
sizeof
section
);
macho_add_dwarf_section
(
state
,
descriptor
,
section
.
sectname
,
offset
+
section
.
offset
,
section
.
size
,
error_callback
,
data
,
dwarf_sections
);
}
break
;
case
MACH_O_LC_SEGMENT_64
:
{
struct
macho_section_64
section
;
memcpy
(
&
section
,
psecs
+
secoffset
,
sizeof
section
);
macho_add_dwarf_section
(
state
,
descriptor
,
section
.
sectname
,
offset
+
section
.
offset
,
section
.
size
,
error_callback
,
data
,
dwarf_sections
);
}
break
;
default:
abort
();
}
secoffset
+=
sec_header_size
;
}
return
1
;
}
/* Compare struct macho_symbol for qsort. */
static
int
macho_symbol_compare
(
const
void
*
v1
,
const
void
*
v2
)
{
const
struct
macho_symbol
*
m1
=
(
const
struct
macho_symbol
*
)
v1
;
const
struct
macho_symbol
*
m2
=
(
const
struct
macho_symbol
*
)
v2
;
if
(
m1
->
address
<
m2
->
address
)
return
-
1
;
else
if
(
m1
->
address
>
m2
->
address
)
return
1
;
else
return
0
;
}
/* Compare an address against a macho_symbol for bsearch. We allocate
one extra entry in the array so that this can safely look at the
next entry. */
static
int
macho_symbol_search
(
const
void
*
vkey
,
const
void
*
ventry
)
{
const
uintptr_t
*
key
=
(
const
uintptr_t
*
)
vkey
;
const
struct
macho_symbol
*
entry
=
(
const
struct
macho_symbol
*
)
ventry
;
uintptr_t
addr
;
addr
=
*
key
;
if
(
addr
<
entry
->
address
)
return
-
1
;
else
if
(
entry
->
name
[
0
]
==
'\0'
&&
entry
->
address
==
~
(
uintptr_t
)
0
)
return
-
1
;
else
if
((
entry
+
1
)
->
name
[
0
]
==
'\0'
&&
(
entry
+
1
)
->
address
==
~
(
uintptr_t
)
0
)
return
-
1
;
else
if
(
addr
>=
(
entry
+
1
)
->
address
)
return
1
;
else
return
0
;
}
/* Return whether the symbol type field indicates a symbol table entry
that we care about: a function or data symbol. */
static
int
macho_defined_symbol
(
uint8_t
type
)
{
if
((
type
&
MACH_O_N_STAB
)
!=
0
)
return
0
;
if
((
type
&
MACH_O_N_EXT
)
!=
0
)
return
0
;
switch
(
type
&
MACH_O_N_TYPE
)
{
case
MACH_O_N_ABS
:
return
1
;
case
MACH_O_N_SECT
:
return
1
;
default:
return
0
;
}
}
/* Add symbol table information for a Mach-O file. */
static
int
macho_add_symtab
(
struct
backtrace_state
*
state
,
int
descriptor
,
uintptr_t
base_address
,
int
is_64
,
off_t
symoff
,
unsigned
int
nsyms
,
off_t
stroff
,
unsigned
int
strsize
,
backtrace_error_callback
error_callback
,
void
*
data
)
{
size_t
symsize
;
struct
backtrace_view
sym_view
;
int
sym_view_valid
;
struct
backtrace_view
str_view
;
int
str_view_valid
;
size_t
ndefs
;
size_t
symtaboff
;
unsigned
int
i
;
size_t
macho_symbol_size
;
struct
macho_symbol
*
macho_symbols
;
unsigned
int
j
;
struct
macho_syminfo_data
*
sdata
;
sym_view_valid
=
0
;
str_view_valid
=
0
;
macho_symbol_size
=
0
;
macho_symbols
=
NULL
;
if
(
is_64
)
symsize
=
sizeof
(
struct
macho_nlist_64
);
else
symsize
=
sizeof
(
struct
macho_nlist
);
if
(
!
backtrace_get_view
(
state
,
descriptor
,
symoff
,
nsyms
*
symsize
,
error_callback
,
data
,
&
sym_view
))
goto
fail
;
sym_view_valid
=
1
;
if
(
!
backtrace_get_view
(
state
,
descriptor
,
stroff
,
strsize
,
error_callback
,
data
,
&
str_view
))
return
0
;
str_view_valid
=
1
;
ndefs
=
0
;
symtaboff
=
0
;
for
(
i
=
0
;
i
<
nsyms
;
++
i
,
symtaboff
+=
symsize
)
{
if
(
is_64
)
{
struct
macho_nlist_64
nlist
;
memcpy
(
&
nlist
,
(
const
char
*
)
sym_view
.
data
+
symtaboff
,
sizeof
nlist
);
if
(
macho_defined_symbol
(
nlist
.
n_type
))
++
ndefs
;
}
else
{
struct
macho_nlist
nlist
;
memcpy
(
&
nlist
,
(
const
char
*
)
sym_view
.
data
+
symtaboff
,
sizeof
nlist
);
if
(
macho_defined_symbol
(
nlist
.
n_type
))
++
ndefs
;
}
}
/* Add 1 to ndefs to make room for a sentinel. */
macho_symbol_size
=
(
ndefs
+
1
)
*
sizeof
(
struct
macho_symbol
);
macho_symbols
=
((
struct
macho_symbol
*
)
backtrace_alloc
(
state
,
macho_symbol_size
,
error_callback
,
data
));
if
(
macho_symbols
==
NULL
)
goto
fail
;
j
=
0
;
symtaboff
=
0
;
for
(
i
=
0
;
i
<
nsyms
;
++
i
,
symtaboff
+=
symsize
)
{
uint32_t
strx
;
uint64_t
value
;
const
char
*
name
;
strx
=
0
;
value
=
0
;
if
(
is_64
)
{
struct
macho_nlist_64
nlist
;
memcpy
(
&
nlist
,
(
const
char
*
)
sym_view
.
data
+
symtaboff
,
sizeof
nlist
);
if
(
!
macho_defined_symbol
(
nlist
.
n_type
))
continue
;
strx
=
nlist
.
n_strx
;
value
=
nlist
.
n_value
;
}
else
{
struct
macho_nlist
nlist
;
memcpy
(
&
nlist
,
(
const
char
*
)
sym_view
.
data
+
symtaboff
,
sizeof
nlist
);
if
(
!
macho_defined_symbol
(
nlist
.
n_type
))
continue
;
strx
=
nlist
.
n_strx
;
value
=
nlist
.
n_value
;
}
if
(
strx
>=
strsize
)
{
error_callback
(
data
,
"symbol string index out of range"
,
0
);
goto
fail
;
}
name
=
(
const
char
*
)
str_view
.
data
+
strx
;
if
(
name
[
0
]
==
'_'
)
++
name
;
macho_symbols
[
j
].
name
=
name
;
macho_symbols
[
j
].
address
=
value
+
base_address
;
++
j
;
}
sdata
=
((
struct
macho_syminfo_data
*
)
backtrace_alloc
(
state
,
sizeof
*
sdata
,
error_callback
,
data
));
if
(
sdata
==
NULL
)
goto
fail
;
/* We need to keep the string table since it holds the names, but we
can release the symbol table. */
backtrace_release_view
(
state
,
&
sym_view
,
error_callback
,
data
);
sym_view_valid
=
0
;
str_view_valid
=
0
;
/* Add a trailing sentinel symbol. */
macho_symbols
[
j
].
name
=
""
;
macho_symbols
[
j
].
address
=
~
(
uintptr_t
)
0
;
backtrace_qsort
(
macho_symbols
,
ndefs
+
1
,
sizeof
(
struct
macho_symbol
),
macho_symbol_compare
);
sdata
->
next
=
NULL
;
sdata
->
symbols
=
macho_symbols
;
sdata
->
count
=
ndefs
;
if
(
!
state
->
threaded
)
{
struct
macho_syminfo_data
**
pp
;
for
(
pp
=
(
struct
macho_syminfo_data
**
)
(
void
*
)
&
state
->
syminfo_data
;
*
pp
!=
NULL
;
pp
=
&
(
*
pp
)
->
next
)
;
*
pp
=
sdata
;
}
else
{
while
(
1
)
{
struct
macho_syminfo_data
**
pp
;
pp
=
(
struct
macho_syminfo_data
**
)
(
void
*
)
&
state
->
syminfo_data
;
while
(
1
)
{
struct
macho_syminfo_data
*
p
;
p
=
backtrace_atomic_load_pointer
(
pp
);
if
(
p
==
NULL
)
break
;
pp
=
&
p
->
next
;
}
if
(
__sync_bool_compare_and_swap
(
pp
,
NULL
,
sdata
))
break
;
}
}
return
1
;
fail:
if
(
macho_symbols
!=
NULL
)
backtrace_free
(
state
,
macho_symbols
,
macho_symbol_size
,
error_callback
,
data
);
if
(
sym_view_valid
)
backtrace_release_view
(
state
,
&
sym_view
,
error_callback
,
data
);
if
(
str_view_valid
)
backtrace_release_view
(
state
,
&
str_view
,
error_callback
,
data
);
return
0
;
}
/* Return the symbol name and value for an ADDR. */
static
void
macho_syminfo
(
struct
backtrace_state
*
state
,
uintptr_t
addr
,
backtrace_syminfo_callback
callback
,
backtrace_error_callback
error_callback
ATTRIBUTE_UNUSED
,
void
*
data
)
{
struct
macho_syminfo_data
*
sdata
;
struct
macho_symbol
*
sym
;
sym
=
NULL
;
if
(
!
state
->
threaded
)
{
for
(
sdata
=
(
struct
macho_syminfo_data
*
)
state
->
syminfo_data
;
sdata
!=
NULL
;
sdata
=
sdata
->
next
)
{
sym
=
((
struct
macho_symbol
*
)
bsearch
(
&
addr
,
sdata
->
symbols
,
sdata
->
count
,
sizeof
(
struct
macho_symbol
),
macho_symbol_search
));
if
(
sym
!=
NULL
)
break
;
}
}
else
{
struct
macho_syminfo_data
**
pp
;
pp
=
(
struct
macho_syminfo_data
**
)
(
void
*
)
&
state
->
syminfo_data
;
while
(
1
)
{
sdata
=
backtrace_atomic_load_pointer
(
pp
);
if
(
sdata
==
NULL
)
break
;
sym
=
((
struct
macho_symbol
*
)
bsearch
(
&
addr
,
sdata
->
symbols
,
sdata
->
count
,
sizeof
(
struct
macho_symbol
),
macho_symbol_search
));
if
(
sym
!=
NULL
)
break
;
pp
=
&
sdata
->
next
;
}
}
if
(
sym
==
NULL
)
callback
(
data
,
addr
,
NULL
,
0
,
0
);
else
callback
(
data
,
addr
,
sym
->
name
,
sym
->
address
,
0
);
}
/* Look through a fat file to find the relevant executable. Returns 1
on success, 0 on failure (in both cases descriptor is closed). */
static
int
macho_add_fat
(
struct
backtrace_state
*
state
,
const
char
*
filename
,
int
descriptor
,
int
swapped
,
off_t
offset
,
const
unsigned
char
*
match_uuid
,
uintptr_t
base_address
,
int
skip_symtab
,
uint32_t
nfat_arch
,
backtrace_error_callback
error_callback
,
void
*
data
,
fileline
*
fileline_fn
,
int
*
found_sym
)
{
int
arch_view_valid
;
unsigned
int
cputype
;
struct
backtrace_view
arch_view
;
size_t
archoffset
;
unsigned
int
i
;
arch_view_valid
=
0
;
#if defined (__x86_64__)
cputype
=
MACH_O_CPU_TYPE_X86_64
;
#elif defined (__i386__)
cputype
=
MACH_O_CPU_TYPE_X86
;
#elif defined (__aarch64__)
cputype
=
MACH_O_CPU_TYPE_ARM64
;
#elif defined (__arm__)
cputype
=
MACH_O_CPU_TYPE_ARM
;
#else
error_callback
(
data
,
"unknown Mach-O architecture"
,
0
);
goto
fail
;
#endif
if
(
!
backtrace_get_view
(
state
,
descriptor
,
offset
,
nfat_arch
*
sizeof
(
struct
macho_fat_arch
),
error_callback
,
data
,
&
arch_view
))
goto
fail
;
archoffset
=
0
;
for
(
i
=
0
;
i
<
nfat_arch
;
++
i
)
{
struct
macho_fat_arch
fat_arch
;
uint32_t
fcputype
;
memcpy
(
&
fat_arch
,
((
const
char
*
)
arch_view
.
data
+
i
*
sizeof
(
struct
macho_fat_arch
)),
sizeof
fat_arch
);
fcputype
=
fat_arch
.
cputype
;
if
(
swapped
)
fcputype
=
__builtin_bswap32
(
fcputype
);
if
(
fcputype
==
cputype
)
{
uint32_t
foffset
;
/* FIXME: What about cpusubtype? */
foffset
=
fat_arch
.
offset
;
if
(
swapped
)
foffset
=
__builtin_bswap32
(
foffset
);
backtrace_release_view
(
state
,
&
arch_view
,
error_callback
,
data
);
return
macho_add
(
state
,
filename
,
descriptor
,
foffset
,
match_uuid
,
base_address
,
skip_symtab
,
error_callback
,
data
,
fileline_fn
,
found_sym
);
}
archoffset
+=
sizeof
(
struct
macho_fat_arch
);
}
error_callback
(
data
,
"could not find executable in fat file"
,
0
);
fail:
if
(
arch_view_valid
)
backtrace_release_view
(
state
,
&
arch_view
,
error_callback
,
data
);
if
(
descriptor
!=
-
1
)
backtrace_close
(
descriptor
,
error_callback
,
data
);
return
0
;
}
/* Look for the dsym file for FILENAME. This is called if FILENAME
does not have debug info or a symbol table. Returns 1 on success,
0 on failure. */
static
int
macho_add_dsym
(
struct
backtrace_state
*
state
,
const
char
*
filename
,
uintptr_t
base_address
,
const
unsigned
char
*
uuid
,
backtrace_error_callback
error_callback
,
void
*
data
,
fileline
*
fileline_fn
)
{
const
char
*
p
;
const
char
*
dirname
;
char
*
diralc
;
size_t
dirnamelen
;
const
char
*
basename
;
size_t
basenamelen
;
const
char
*
dsymsuffixdir
;
size_t
dsymsuffixdirlen
;
size_t
dsymlen
;
char
*
dsym
;
char
*
ps
;
int
d
;
int
does_not_exist
;
int
dummy_found_sym
;
diralc
=
NULL
;
dirnamelen
=
0
;
dsym
=
NULL
;
dsymlen
=
0
;
p
=
strrchr
(
filename
,
'/'
);
if
(
p
==
NULL
)
{
dirname
=
"."
;
dirnamelen
=
1
;
basename
=
filename
;
basenamelen
=
strlen
(
basename
);
diralc
=
NULL
;
}
else
{
dirnamelen
=
p
-
filename
;
diralc
=
backtrace_alloc
(
state
,
dirnamelen
+
1
,
error_callback
,
data
);
if
(
diralc
==
NULL
)
goto
fail
;
memcpy
(
diralc
,
filename
,
dirnamelen
);
diralc
[
dirnamelen
]
=
'\0'
;
dirname
=
diralc
;
basename
=
p
+
1
;
basenamelen
=
strlen
(
basename
);
}
dsymsuffixdir
=
".dSYM/Contents/Resources/DWARF/"
;
dsymsuffixdirlen
=
strlen
(
dsymsuffixdir
);
dsymlen
=
(
dirnamelen
+
basenamelen
+
dsymsuffixdirlen
+
basenamelen
+
1
);
dsym
=
backtrace_alloc
(
state
,
dsymlen
,
error_callback
,
data
);
if
(
dsym
==
NULL
)
goto
fail
;
ps
=
dsym
;
memcpy
(
ps
,
dirname
,
dirnamelen
);
ps
+=
dirnamelen
;
*
ps
++
=
'/'
;
memcpy
(
ps
,
basename
,
basenamelen
);
ps
+=
basenamelen
;
memcpy
(
ps
,
dsymsuffixdir
,
dsymsuffixdirlen
);
ps
+=
dsymsuffixdirlen
;
memcpy
(
ps
,
basename
,
basenamelen
);
ps
+=
basenamelen
;
*
ps
=
'\0'
;
if
(
diralc
!=
NULL
)
{
backtrace_free
(
state
,
diralc
,
dirnamelen
,
error_callback
,
data
);
diralc
=
NULL
;
}
d
=
backtrace_open
(
dsym
,
error_callback
,
data
,
&
does_not_exist
);
if
(
d
<
0
)
{
/* The file does not exist, so we can't read the debug info.
Just return success. */
backtrace_free
(
state
,
dsym
,
dsymlen
,
error_callback
,
data
);
return
1
;
}
if
(
!
macho_add
(
state
,
dsym
,
d
,
0
,
uuid
,
base_address
,
1
,
error_callback
,
data
,
fileline_fn
,
&
dummy_found_sym
))
goto
fail
;
backtrace_free
(
state
,
dsym
,
dsymlen
,
error_callback
,
data
);
return
1
;
fail:
if
(
dsym
!=
NULL
)
backtrace_free
(
state
,
dsym
,
dsymlen
,
error_callback
,
data
);
if
(
diralc
!=
NULL
)
backtrace_free
(
state
,
diralc
,
dirnamelen
,
error_callback
,
data
);
return
0
;
}
/* Add the backtrace data for a Macho-O file. Returns 1 on success, 0
on failure (in both cases descriptor is closed).
FILENAME: the name of the executable.
DESCRIPTOR: an open descriptor for the executable, closed here.
OFFSET: the offset within the file of this executable, for fat files.
MATCH_UUID: if not NULL, UUID that must match.
BASE_ADDRESS: the load address of the executable.
SKIP_SYMTAB: if non-zero, ignore the symbol table; used for dSYM files.
FILELINE_FN: set to the fileline function, by backtrace_dwarf_add.
FOUND_SYM: set to non-zero if we found the symbol table.
*/
static
int
macho_add
(
struct
backtrace_state
*
state
,
const
char
*
filename
,
int
descriptor
,
off_t
offset
,
const
unsigned
char
*
match_uuid
,
uintptr_t
base_address
,
int
skip_symtab
,
backtrace_error_callback
error_callback
,
void
*
data
,
fileline
*
fileline_fn
,
int
*
found_sym
)
{
struct
backtrace_view
header_view
;
struct
macho_header_32
header
;
off_t
hdroffset
;
int
is_64
;
struct
backtrace_view
cmds_view
;
int
cmds_view_valid
;
struct
dwarf_sections
dwarf_sections
;
int
have_dwarf
;
unsigned
char
uuid
[
MACH_O_UUID_LEN
];
int
have_uuid
;
size_t
cmdoffset
;
unsigned
int
i
;
*
found_sym
=
0
;
cmds_view_valid
=
0
;
/* The 32-bit and 64-bit file headers start out the same, so we can
just always read the 32-bit version. A fat header is shorter but
it will always be followed by data, so it's OK to read extra. */
if
(
!
backtrace_get_view
(
state
,
descriptor
,
offset
,
sizeof
(
struct
macho_header_32
),
error_callback
,
data
,
&
header_view
))
goto
fail
;
memcpy
(
&
header
,
header_view
.
data
,
sizeof
header
);
backtrace_release_view
(
state
,
&
header_view
,
error_callback
,
data
);
switch
(
header
.
magic
)
{
case
MACH_O_MH_MAGIC_32
:
is_64
=
0
;
hdroffset
=
offset
+
sizeof
(
struct
macho_header_32
);
break
;
case
MACH_O_MH_MAGIC_64
:
is_64
=
1
;
hdroffset
=
offset
+
sizeof
(
struct
macho_header_64
);
break
;
case
MACH_O_MH_MAGIC_FAT
:
{
struct
macho_header_fat
fat_header
;
hdroffset
=
offset
+
sizeof
(
struct
macho_header_fat
);
memcpy
(
&
fat_header
,
&
header
,
sizeof
fat_header
);
return
macho_add_fat
(
state
,
filename
,
descriptor
,
0
,
hdroffset
,
match_uuid
,
base_address
,
skip_symtab
,
fat_header
.
nfat_arch
,
error_callback
,
data
,
fileline_fn
,
found_sym
);
}
case
MACH_O_MH_CIGAM_FAT
:
{
struct
macho_header_fat
fat_header
;
uint32_t
nfat_arch
;
hdroffset
=
offset
+
sizeof
(
struct
macho_header_fat
);
memcpy
(
&
fat_header
,
&
header
,
sizeof
fat_header
);
nfat_arch
=
__builtin_bswap32
(
fat_header
.
nfat_arch
);
return
macho_add_fat
(
state
,
filename
,
descriptor
,
1
,
hdroffset
,
match_uuid
,
base_address
,
skip_symtab
,
nfat_arch
,
error_callback
,
data
,
fileline_fn
,
found_sym
);
}
default:
error_callback
(
data
,
"executable file is not in Mach-O format"
,
0
);
goto
fail
;
}
switch
(
header
.
filetype
)
{
case
MACH_O_MH_EXECUTE
:
case
MACH_O_MH_DYLIB
:
case
MACH_O_MH_DSYM
:
break
;
default:
error_callback
(
data
,
"executable file is not an executable"
,
0
);
goto
fail
;
}
if
(
!
backtrace_get_view
(
state
,
descriptor
,
hdroffset
,
header
.
sizeofcmds
,
error_callback
,
data
,
&
cmds_view
))
goto
fail
;
cmds_view_valid
=
1
;
memset
(
&
dwarf_sections
,
0
,
sizeof
dwarf_sections
);
have_dwarf
=
0
;
memset
(
&
uuid
,
0
,
sizeof
uuid
);
have_uuid
=
0
;
cmdoffset
=
0
;
for
(
i
=
0
;
i
<
header
.
ncmds
;
++
i
)
{
const
char
*
pcmd
;
struct
macho_load_command
load_command
;
if
(
cmdoffset
+
sizeof
load_command
>
header
.
sizeofcmds
)
break
;
pcmd
=
(
const
char
*
)
cmds_view
.
data
+
cmdoffset
;
memcpy
(
&
load_command
,
pcmd
,
sizeof
load_command
);
switch
(
load_command
.
cmd
)
{
case
MACH_O_LC_SEGMENT
:
{
struct
macho_segment_command
segcmd
;
memcpy
(
&
segcmd
,
pcmd
,
sizeof
segcmd
);
if
(
memcmp
(
segcmd
.
segname
,
"__DWARF
\0\0\0\0\0\0\0\0\0
"
,
MACH_O_NAMELEN
)
==
0
)
{
if
(
!
macho_add_dwarf_segment
(
state
,
descriptor
,
offset
,
load_command
.
cmd
,
pcmd
+
sizeof
segcmd
,
(
load_command
.
cmdsize
-
sizeof
segcmd
),
segcmd
.
nsects
,
error_callback
,
data
,
&
dwarf_sections
))
goto
fail
;
have_dwarf
=
1
;
}
}
break
;
case
MACH_O_LC_SEGMENT_64
:
{
struct
macho_segment_64_command
segcmd
;
memcpy
(
&
segcmd
,
pcmd
,
sizeof
segcmd
);
if
(
memcmp
(
segcmd
.
segname
,
"__DWARF
\0\0\0\0\0\0\0\0\0
"
,
MACH_O_NAMELEN
)
==
0
)
{
if
(
!
macho_add_dwarf_segment
(
state
,
descriptor
,
offset
,
load_command
.
cmd
,
pcmd
+
sizeof
segcmd
,
(
load_command
.
cmdsize
-
sizeof
segcmd
),
segcmd
.
nsects
,
error_callback
,
data
,
&
dwarf_sections
))
goto
fail
;
have_dwarf
=
1
;
}
}
break
;
case
MACH_O_LC_SYMTAB
:
if
(
!
skip_symtab
)
{
struct
macho_symtab_command
symcmd
;
memcpy
(
&
symcmd
,
pcmd
,
sizeof
symcmd
);
if
(
!
macho_add_symtab
(
state
,
descriptor
,
base_address
,
is_64
,
offset
+
symcmd
.
symoff
,
symcmd
.
nsyms
,
offset
+
symcmd
.
stroff
,
symcmd
.
strsize
,
error_callback
,
data
))
goto
fail
;
*
found_sym
=
1
;
}
break
;
case
MACH_O_LC_UUID
:
{
struct
macho_uuid_command
uuidcmd
;
memcpy
(
&
uuidcmd
,
pcmd
,
sizeof
uuidcmd
);
memcpy
(
&
uuid
[
0
],
&
uuidcmd
.
uuid
[
0
],
MACH_O_UUID_LEN
);
have_uuid
=
1
;
}
break
;
default:
break
;
}
cmdoffset
+=
load_command
.
cmdsize
;
}
if
(
!
backtrace_close
(
descriptor
,
error_callback
,
data
))
goto
fail
;
descriptor
=
-
1
;
backtrace_release_view
(
state
,
&
cmds_view
,
error_callback
,
data
);
cmds_view_valid
=
0
;
if
(
match_uuid
!=
NULL
)
{
/* If we don't have a UUID, or it doesn't match, just ignore
this file. */
if
(
!
have_uuid
||
memcmp
(
match_uuid
,
&
uuid
[
0
],
MACH_O_UUID_LEN
)
!=
0
)
return
1
;
}
if
(
have_dwarf
)
{
int
is_big_endian
;
is_big_endian
=
0
;
#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__)
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
is_big_endian
=
1
;
#endif
#endif
if
(
!
backtrace_dwarf_add
(
state
,
base_address
,
&
dwarf_sections
,
is_big_endian
,
NULL
,
error_callback
,
data
,
fileline_fn
,
NULL
))
goto
fail
;
}
if
(
!
have_dwarf
&&
have_uuid
)
{
if
(
!
macho_add_dsym
(
state
,
filename
,
base_address
,
&
uuid
[
0
],
error_callback
,
data
,
fileline_fn
))
goto
fail
;
}
return
1
;
fail:
if
(
cmds_view_valid
)
backtrace_release_view
(
state
,
&
cmds_view
,
error_callback
,
data
);
if
(
descriptor
!=
-
1
)
backtrace_close
(
descriptor
,
error_callback
,
data
);
return
0
;
}
#ifdef HAVE_MACH_O_DYLD_H
/* Initialize the backtrace data we need from a Mach-O executable
using the dyld support functions. This closes descriptor. */
int
backtrace_initialize
(
struct
backtrace_state
*
state
,
const
char
*
filename
,
int
descriptor
,
backtrace_error_callback
error_callback
,
void
*
data
,
fileline
*
fileline_fn
)
{
uint32_t
c
;
uint32_t
i
;
int
closed_descriptor
;
int
found_sym
;
fileline
macho_fileline_fn
;
closed_descriptor
=
0
;
found_sym
=
0
;
macho_fileline_fn
=
macho_nodebug
;
c
=
_dyld_image_count
();
for
(
i
=
0
;
i
<
c
;
++
i
)
{
uintptr_t
base_address
;
const
char
*
name
;
int
d
;
fileline
mff
;
int
mfs
;
name
=
_dyld_get_image_name
(
i
);
if
(
name
==
NULL
)
continue
;
if
(
strcmp
(
name
,
filename
)
==
0
&&
!
closed_descriptor
)
{
d
=
descriptor
;
closed_descriptor
=
1
;
}
else
{
int
does_not_exist
;
d
=
backtrace_open
(
name
,
error_callback
,
data
,
&
does_not_exist
);
if
(
d
<
0
)
continue
;
}
base_address
=
_dyld_get_image_vmaddr_slide
(
i
);
mff
=
macho_nodebug
;
if
(
!
macho_add
(
state
,
name
,
d
,
0
,
NULL
,
base_address
,
0
,
error_callback
,
data
,
&
mff
,
&
mfs
))
return
0
;
if
(
mff
!=
macho_nodebug
)
macho_fileline_fn
=
mff
;
if
(
mfs
)
found_sym
=
1
;
}
if
(
!
closed_descriptor
)
backtrace_close
(
descriptor
,
error_callback
,
data
);
if
(
!
state
->
threaded
)
{
if
(
found_sym
)
state
->
syminfo_fn
=
macho_syminfo
;
else
if
(
state
->
syminfo_fn
==
NULL
)
state
->
syminfo_fn
=
macho_nosyms
;
}
else
{
if
(
found_sym
)
backtrace_atomic_store_pointer
(
&
state
->
syminfo_fn
,
macho_syminfo
);
else
(
void
)
__sync_bool_compare_and_swap
(
&
state
->
syminfo_fn
,
NULL
,
macho_nosyms
);
}
if
(
!
state
->
threaded
)
*
fileline_fn
=
state
->
fileline_fn
;
else
*
fileline_fn
=
backtrace_atomic_load_pointer
(
&
state
->
fileline_fn
);
if
(
*
fileline_fn
==
NULL
||
*
fileline_fn
==
macho_nodebug
)
*
fileline_fn
=
macho_fileline_fn
;
return
1
;
}
#else
/* !defined (HAVE_MACH_O_DYLD_H) */
/* Initialize the backtrace data we need from a Mach-O executable
without using the dyld support functions. This closes
descriptor. */
int
backtrace_initialize
(
struct
backtrace_state
*
state
,
const
char
*
filename
,
int
descriptor
,
backtrace_error_callback
error_callback
,
void
*
data
,
fileline
*
fileline_fn
)
{
fileline
macho_fileline_fn
;
int
found_sym
;
macho_fileline_fn
=
macho_nodebug
;
if
(
!
macho_add
(
state
,
filename
,
descriptor
,
0
,
NULL
,
0
,
0
,
error_callback
,
data
,
&
macho_fileline_fn
,
&
found_sym
))
return
0
;
if
(
!
state
->
threaded
)
{
if
(
found_sym
)
state
->
syminfo_fn
=
macho_syminfo
;
else
if
(
state
->
syminfo_fn
==
NULL
)
state
->
syminfo_fn
=
macho_nosyms
;
}
else
{
if
(
found_sym
)
backtrace_atomic_store_pointer
(
&
state
->
syminfo_fn
,
macho_syminfo
);
else
(
void
)
__sync_bool_compare_and_swap
(
&
state
->
syminfo_fn
,
NULL
,
macho_nosyms
);
}
if
(
!
state
->
threaded
)
*
fileline_fn
=
state
->
fileline_fn
;
else
*
fileline_fn
=
backtrace_atomic_load_pointer
(
&
state
->
fileline_fn
);
if
(
*
fileline_fn
==
NULL
||
*
fileline_fn
==
macho_nodebug
)
*
fileline_fn
=
macho_fileline_fn
;
return
1
;
}
#endif
/* !defined (HAVE_MACH_O_DYLD_H) */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment