1*4d9fdb46SRobert Mustacchi /*
2*4d9fdb46SRobert Mustacchi Copyright (c) 2019, David Anderson
3*4d9fdb46SRobert Mustacchi All rights reserved.
4*4d9fdb46SRobert Mustacchi cc
5*4d9fdb46SRobert Mustacchi Redistribution and use in source and binary forms, with
6*4d9fdb46SRobert Mustacchi or without modification, are permitted provided that the
7*4d9fdb46SRobert Mustacchi following conditions are met:
8*4d9fdb46SRobert Mustacchi 
9*4d9fdb46SRobert Mustacchi     Redistributions of source code must retain the above
10*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
11*4d9fdb46SRobert Mustacchi     disclaimer.
12*4d9fdb46SRobert Mustacchi 
13*4d9fdb46SRobert Mustacchi     Redistributions in binary form must reproduce the above
14*4d9fdb46SRobert Mustacchi     copyright notice, this list of conditions and the following
15*4d9fdb46SRobert Mustacchi     disclaimer in the documentation and/or other materials
16*4d9fdb46SRobert Mustacchi     provided with the distribution.
17*4d9fdb46SRobert Mustacchi 
18*4d9fdb46SRobert Mustacchi THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19*4d9fdb46SRobert Mustacchi CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20*4d9fdb46SRobert Mustacchi INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21*4d9fdb46SRobert Mustacchi OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22*4d9fdb46SRobert Mustacchi ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23*4d9fdb46SRobert Mustacchi CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4d9fdb46SRobert Mustacchi SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25*4d9fdb46SRobert Mustacchi NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26*4d9fdb46SRobert Mustacchi LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*4d9fdb46SRobert Mustacchi HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28*4d9fdb46SRobert Mustacchi CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*4d9fdb46SRobert Mustacchi OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*4d9fdb46SRobert Mustacchi EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4d9fdb46SRobert Mustacchi */
32*4d9fdb46SRobert Mustacchi 
33*4d9fdb46SRobert Mustacchi /*  This file reads the parts of an Apple mach-o object
34*4d9fdb46SRobert Mustacchi     file appropriate to reading DWARF debugging data.
35*4d9fdb46SRobert Mustacchi     Overview:
36*4d9fdb46SRobert Mustacchi     _dwarf_macho_setup() Does all macho setup.
37*4d9fdb46SRobert Mustacchi         calls _dwarf_macho_access_init()
38*4d9fdb46SRobert Mustacchi             calls _dwarf_macho_object_access_internals_init()
39*4d9fdb46SRobert Mustacchi                 Creates internals record 'M',
40*4d9fdb46SRobert Mustacchi                     dwarf_macho_object_access_internals_t
41*4d9fdb46SRobert Mustacchi                 Sets flags/data in internals record
42*4d9fdb46SRobert Mustacchi                 Loads macho object data needed later.
43*4d9fdb46SRobert Mustacchi                 Sets methods struct to access macho object.
44*4d9fdb46SRobert Mustacchi         calls _dwarf_object_init_b() Creates Dwarf_Debug, independent
45*4d9fdb46SRobert Mustacchi             of any macho code.
46*4d9fdb46SRobert Mustacchi         Sets internals record into dbg.
47*4d9fdb46SRobert Mustacchi     ----------------------
48*4d9fdb46SRobert Mustacchi     _dwarf_destruct_macho_access(). This frees
49*4d9fdb46SRobert Mustacchi         the macho internals record created in
50*4d9fdb46SRobert Mustacchi         _dwarf_macho_object_access_internals_init()
51*4d9fdb46SRobert Mustacchi         in case of errors during setup or when
52*4d9fdb46SRobert Mustacchi         dwarf_finish() is called.  Works safely for
53*4d9fdb46SRobert Mustacchi         partially or fully set-up macho internals record.
54*4d9fdb46SRobert Mustacchi 
55*4d9fdb46SRobert Mustacchi     Other than in _dwarf_macho_setup() the macho code
56*4d9fdb46SRobert Mustacchi     knows nothing about Dwarf_Debug, and the rest of
57*4d9fdb46SRobert Mustacchi     libdwarf knows nothing about the content of the
58*4d9fdb46SRobert Mustacchi     macho internals record.
59*4d9fdb46SRobert Mustacchi 
60*4d9fdb46SRobert Mustacchi */
61*4d9fdb46SRobert Mustacchi 
62*4d9fdb46SRobert Mustacchi #ifdef _WIN32
63*4d9fdb46SRobert Mustacchi #define _CRT_SECURE_NO_WARNINGS
64*4d9fdb46SRobert Mustacchi #endif /* _WIN32 */
65*4d9fdb46SRobert Mustacchi 
66*4d9fdb46SRobert Mustacchi #include "config.h"
67*4d9fdb46SRobert Mustacchi #include <stdio.h>
68*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
69*4d9fdb46SRobert Mustacchi #include <stdlib.h>
70*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
71*4d9fdb46SRobert Mustacchi #ifdef HAVE_MALLOC_H
72*4d9fdb46SRobert Mustacchi /* Useful include for some Windows compilers. */
73*4d9fdb46SRobert Mustacchi #include <malloc.h>
74*4d9fdb46SRobert Mustacchi #endif /* HAVE_MALLOC_H */
75*4d9fdb46SRobert Mustacchi #include <string.h>
76*4d9fdb46SRobert Mustacchi #include <sys/types.h> /* open() */
77*4d9fdb46SRobert Mustacchi #include <sys/stat.h> /* open() */
78*4d9fdb46SRobert Mustacchi #include <fcntl.h> /* open() */
79*4d9fdb46SRobert Mustacchi #include <time.h>
80*4d9fdb46SRobert Mustacchi #ifdef HAVE_UNISTD_H
81*4d9fdb46SRobert Mustacchi #include <unistd.h> /* lseek read close */
82*4d9fdb46SRobert Mustacchi #elif defined(_WIN32) && defined(_MSC_VER)
83*4d9fdb46SRobert Mustacchi #include <io.h>
84*4d9fdb46SRobert Mustacchi #endif /* HAVE_UNISTD_H */
85*4d9fdb46SRobert Mustacchi 
86*4d9fdb46SRobert Mustacchi /* Windows specific header files */
87*4d9fdb46SRobert Mustacchi #if defined(_WIN32) && defined(HAVE_STDAFX_H)
88*4d9fdb46SRobert Mustacchi #include "stdafx.h"
89*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDAFX_H */
90*4d9fdb46SRobert Mustacchi 
91*4d9fdb46SRobert Mustacchi #include "libdwarf.h"
92*4d9fdb46SRobert Mustacchi #include "libdwarfdefs.h"
93*4d9fdb46SRobert Mustacchi #include "dwarf_base_types.h"
94*4d9fdb46SRobert Mustacchi #include "dwarf_opaque.h"
95*4d9fdb46SRobert Mustacchi #include "dwarf_error.h" /* for _dwarf_error() declaration */
96*4d9fdb46SRobert Mustacchi #include "dwarf_reading.h"
97*4d9fdb46SRobert Mustacchi #include "memcpy_swap.h"
98*4d9fdb46SRobert Mustacchi #include "dwarf_object_read_common.h"
99*4d9fdb46SRobert Mustacchi #include "dwarf_machoread.h"
100*4d9fdb46SRobert Mustacchi #include "dwarf_object_detector.h"
101*4d9fdb46SRobert Mustacchi #include "dwarf_macho_loader.h"
102*4d9fdb46SRobert Mustacchi 
103*4d9fdb46SRobert Mustacchi #ifndef TYP
104*4d9fdb46SRobert Mustacchi #define TYP(n,l) char n[l]
105*4d9fdb46SRobert Mustacchi #endif /* TYPE */
106*4d9fdb46SRobert Mustacchi 
107*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
108*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
109*4d9fdb46SRobert Mustacchi     do {                                        \
110*4d9fdb46SRobert Mustacchi         unsigned tbyte = sizeof(t) - sizeof(s); \
111*4d9fdb46SRobert Mustacchi         t = 0;                                  \
112*4d9fdb46SRobert Mustacchi         func(((char *)&t)+tbyte ,&s[0],sizeof(s));  \
113*4d9fdb46SRobert Mustacchi     } while (0)
114*4d9fdb46SRobert Mustacchi #else /* LITTLE ENDIAN */
115*4d9fdb46SRobert Mustacchi #define ASNAR(func,t,s)                         \
116*4d9fdb46SRobert Mustacchi     do {                                        \
117*4d9fdb46SRobert Mustacchi         t = 0;                                  \
118*4d9fdb46SRobert Mustacchi         func(&t,&s[0],sizeof(s));               \
119*4d9fdb46SRobert Mustacchi     } while (0)
120*4d9fdb46SRobert Mustacchi #endif /* end LITTLE- BIG-ENDIAN */
121*4d9fdb46SRobert Mustacchi 
122*4d9fdb46SRobert Mustacchi 
123*4d9fdb46SRobert Mustacchi /* MACH-O and dwarf section names */
124*4d9fdb46SRobert Mustacchi static struct macho_sect_names_s {
125*4d9fdb46SRobert Mustacchi     char const *ms_moname;
126*4d9fdb46SRobert Mustacchi     char const *ms_dwname;
127*4d9fdb46SRobert Mustacchi } const SectionNames [] = {
128*4d9fdb46SRobert Mustacchi     { "", "" },  /* ELF index-0 entry */
129*4d9fdb46SRobert Mustacchi     { "__debug_abbrev",         ".debug_abbrev" },
130*4d9fdb46SRobert Mustacchi     { "__debug_aranges",        ".debug_aranges" },
131*4d9fdb46SRobert Mustacchi     { "__debug_frame",          ".debug_frame" },
132*4d9fdb46SRobert Mustacchi     { "__debug_info",           ".debug_info" },
133*4d9fdb46SRobert Mustacchi     { "__debug_line",           ".debug_line" },
134*4d9fdb46SRobert Mustacchi     { "__debug_macinfo",        ".debug_macinfo" },
135*4d9fdb46SRobert Mustacchi     { "__debug_loc",            ".debug_loc" },
136*4d9fdb46SRobert Mustacchi     { "__debug_pubnames",       ".debug_pubnames" },
137*4d9fdb46SRobert Mustacchi     { "__debug_pubtypes",       ".debug_pubtypes" },
138*4d9fdb46SRobert Mustacchi     { "__debug_str",            ".debug_str" },
139*4d9fdb46SRobert Mustacchi     { "__debug_ranges",         ".debug_ranges" },
140*4d9fdb46SRobert Mustacchi     { "__debug_macro",          ".debug_macro" },
141*4d9fdb46SRobert Mustacchi     { "__debug_gdb_scri",       ".debug_gdb_scripts" }
142*4d9fdb46SRobert Mustacchi };
143*4d9fdb46SRobert Mustacchi 
144*4d9fdb46SRobert Mustacchi static int
145*4d9fdb46SRobert Mustacchi _dwarf_macho_object_access_init(
146*4d9fdb46SRobert Mustacchi     int  fd,
147*4d9fdb46SRobert Mustacchi     unsigned ftype,
148*4d9fdb46SRobert Mustacchi     unsigned endian,
149*4d9fdb46SRobert Mustacchi     unsigned offsetsize,
150*4d9fdb46SRobert Mustacchi     size_t filesize,
151*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned access,
152*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Interface **binary_interface,
153*4d9fdb46SRobert Mustacchi     int *localerrnum);
154*4d9fdb46SRobert Mustacchi 
155*4d9fdb46SRobert Mustacchi 
macho_get_byte_order(void * obj)156*4d9fdb46SRobert Mustacchi static Dwarf_Endianness macho_get_byte_order (void *obj)
157*4d9fdb46SRobert Mustacchi {
158*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
159*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
160*4d9fdb46SRobert Mustacchi     return macho->mo_endian;
161*4d9fdb46SRobert Mustacchi }
162*4d9fdb46SRobert Mustacchi 
163*4d9fdb46SRobert Mustacchi 
macho_get_length_size(void * obj)164*4d9fdb46SRobert Mustacchi static Dwarf_Small macho_get_length_size (void *obj)
165*4d9fdb46SRobert Mustacchi {
166*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
167*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
168*4d9fdb46SRobert Mustacchi     return macho->mo_offsetsize/8;
169*4d9fdb46SRobert Mustacchi }
170*4d9fdb46SRobert Mustacchi 
171*4d9fdb46SRobert Mustacchi 
macho_get_pointer_size(void * obj)172*4d9fdb46SRobert Mustacchi static Dwarf_Small macho_get_pointer_size (void *obj)
173*4d9fdb46SRobert Mustacchi {
174*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
175*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
176*4d9fdb46SRobert Mustacchi     return macho->mo_pointersize/8;
177*4d9fdb46SRobert Mustacchi }
178*4d9fdb46SRobert Mustacchi 
179*4d9fdb46SRobert Mustacchi 
macho_get_section_count(void * obj)180*4d9fdb46SRobert Mustacchi static Dwarf_Unsigned macho_get_section_count (void *obj)
181*4d9fdb46SRobert Mustacchi {
182*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
183*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
184*4d9fdb46SRobert Mustacchi     return macho->mo_dwarf_sectioncount;
185*4d9fdb46SRobert Mustacchi }
186*4d9fdb46SRobert Mustacchi 
macho_get_section_info(void * obj,Dwarf_Half section_index,Dwarf_Obj_Access_Section * return_section,UNUSEDARG int * error)187*4d9fdb46SRobert Mustacchi static int macho_get_section_info (void *obj,
188*4d9fdb46SRobert Mustacchi     Dwarf_Half section_index,
189*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Section *return_section,
190*4d9fdb46SRobert Mustacchi     UNUSEDARG int *error)
191*4d9fdb46SRobert Mustacchi {
192*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
193*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
194*4d9fdb46SRobert Mustacchi 
195*4d9fdb46SRobert Mustacchi 
196*4d9fdb46SRobert Mustacchi     if (section_index < macho->mo_dwarf_sectioncount) {
197*4d9fdb46SRobert Mustacchi         struct generic_macho_section *sp = 0;
198*4d9fdb46SRobert Mustacchi 
199*4d9fdb46SRobert Mustacchi         sp = macho->mo_dwarf_sections + section_index;
200*4d9fdb46SRobert Mustacchi         return_section->addr = 0;
201*4d9fdb46SRobert Mustacchi         return_section->type = 0;
202*4d9fdb46SRobert Mustacchi         return_section->size = sp->size;
203*4d9fdb46SRobert Mustacchi         return_section->name = sp->dwarfsectname;
204*4d9fdb46SRobert Mustacchi         return_section->link = 0;
205*4d9fdb46SRobert Mustacchi         return_section->info = 0;
206*4d9fdb46SRobert Mustacchi         return_section->entrysize = 0;
207*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
208*4d9fdb46SRobert Mustacchi     }
209*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
210*4d9fdb46SRobert Mustacchi }
211*4d9fdb46SRobert Mustacchi 
212*4d9fdb46SRobert Mustacchi static int
macho_load_section(void * obj,Dwarf_Half section_index,Dwarf_Small ** return_data,int * error)213*4d9fdb46SRobert Mustacchi macho_load_section (void *obj, Dwarf_Half section_index,
214*4d9fdb46SRobert Mustacchi     Dwarf_Small **return_data, int *error)
215*4d9fdb46SRobert Mustacchi {
216*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *macho =
217*4d9fdb46SRobert Mustacchi         (dwarf_macho_object_access_internals_t*)(obj);
218*4d9fdb46SRobert Mustacchi 
219*4d9fdb46SRobert Mustacchi     if (0 < section_index &&
220*4d9fdb46SRobert Mustacchi         section_index < macho->mo_dwarf_sectioncount) {
221*4d9fdb46SRobert Mustacchi         int res = 0;
222*4d9fdb46SRobert Mustacchi 
223*4d9fdb46SRobert Mustacchi         struct generic_macho_section *sp =
224*4d9fdb46SRobert Mustacchi             macho->mo_dwarf_sections + section_index;
225*4d9fdb46SRobert Mustacchi         if(sp->loaded_data) {
226*4d9fdb46SRobert Mustacchi             *return_data = sp->loaded_data;
227*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
228*4d9fdb46SRobert Mustacchi         }
229*4d9fdb46SRobert Mustacchi         if (!sp->size) {
230*4d9fdb46SRobert Mustacchi             return DW_DLV_NO_ENTRY;
231*4d9fdb46SRobert Mustacchi         }
232*4d9fdb46SRobert Mustacchi         if ((sp->size + sp->offset) >
233*4d9fdb46SRobert Mustacchi             macho->mo_filesize) {
234*4d9fdb46SRobert Mustacchi             *error = DW_DLE_FILE_TOO_SMALL;
235*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
236*4d9fdb46SRobert Mustacchi         }
237*4d9fdb46SRobert Mustacchi 
238*4d9fdb46SRobert Mustacchi         sp->loaded_data = malloc((size_t)sp->size);
239*4d9fdb46SRobert Mustacchi         if (!sp->loaded_data) {
240*4d9fdb46SRobert Mustacchi             *error = DW_DLE_ALLOC_FAIL;
241*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
242*4d9fdb46SRobert Mustacchi         }
243*4d9fdb46SRobert Mustacchi         res = RRMOA(macho->mo_fd,
244*4d9fdb46SRobert Mustacchi             sp->loaded_data, (off_t)sp->offset,
245*4d9fdb46SRobert Mustacchi             (size_t)sp->size, (off_t)macho->mo_filesize, error);
246*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
247*4d9fdb46SRobert Mustacchi             free(sp->loaded_data);
248*4d9fdb46SRobert Mustacchi             sp->loaded_data = 0;
249*4d9fdb46SRobert Mustacchi             return res;
250*4d9fdb46SRobert Mustacchi         }
251*4d9fdb46SRobert Mustacchi         *return_data = sp->loaded_data;
252*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
253*4d9fdb46SRobert Mustacchi     }
254*4d9fdb46SRobert Mustacchi     return DW_DLV_NO_ENTRY;
255*4d9fdb46SRobert Mustacchi }
256*4d9fdb46SRobert Mustacchi 
257*4d9fdb46SRobert Mustacchi void
_dwarf_destruct_macho_access(struct Dwarf_Obj_Access_Interface_s * aip)258*4d9fdb46SRobert Mustacchi _dwarf_destruct_macho_access(
259*4d9fdb46SRobert Mustacchi     struct Dwarf_Obj_Access_Interface_s *aip)
260*4d9fdb46SRobert Mustacchi {
261*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mp = 0;
262*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
263*4d9fdb46SRobert Mustacchi 
264*4d9fdb46SRobert Mustacchi     if(!aip) {
265*4d9fdb46SRobert Mustacchi         return;
266*4d9fdb46SRobert Mustacchi     }
267*4d9fdb46SRobert Mustacchi     mp = (dwarf_macho_object_access_internals_t *)aip->object;
268*4d9fdb46SRobert Mustacchi     if (mp->mo_destruct_close_fd) {
269*4d9fdb46SRobert Mustacchi         close(mp->mo_fd);
270*4d9fdb46SRobert Mustacchi         mp->mo_fd = -1;
271*4d9fdb46SRobert Mustacchi     }
272*4d9fdb46SRobert Mustacchi     if (mp->mo_commands){
273*4d9fdb46SRobert Mustacchi         free(mp->mo_commands);
274*4d9fdb46SRobert Mustacchi         mp->mo_commands = 0;
275*4d9fdb46SRobert Mustacchi     }
276*4d9fdb46SRobert Mustacchi     if (mp->mo_segment_commands){
277*4d9fdb46SRobert Mustacchi         free(mp->mo_segment_commands);
278*4d9fdb46SRobert Mustacchi         mp->mo_segment_commands = 0;
279*4d9fdb46SRobert Mustacchi     }
280*4d9fdb46SRobert Mustacchi     free((char *)mp->mo_path);
281*4d9fdb46SRobert Mustacchi     if (mp->mo_dwarf_sections) {
282*4d9fdb46SRobert Mustacchi         struct generic_macho_section *sp = 0;
283*4d9fdb46SRobert Mustacchi 
284*4d9fdb46SRobert Mustacchi         sp = mp->mo_dwarf_sections;
285*4d9fdb46SRobert Mustacchi         for( i=0; i < mp->mo_dwarf_sectioncount; ++i,++sp) {
286*4d9fdb46SRobert Mustacchi             if (sp->loaded_data) {
287*4d9fdb46SRobert Mustacchi                 free(sp->loaded_data);
288*4d9fdb46SRobert Mustacchi                 sp->loaded_data = 0;
289*4d9fdb46SRobert Mustacchi             }
290*4d9fdb46SRobert Mustacchi         }
291*4d9fdb46SRobert Mustacchi         free(mp->mo_dwarf_sections);
292*4d9fdb46SRobert Mustacchi         mp->mo_dwarf_sections = 0;
293*4d9fdb46SRobert Mustacchi     }
294*4d9fdb46SRobert Mustacchi     free(mp);
295*4d9fdb46SRobert Mustacchi     free(aip);
296*4d9fdb46SRobert Mustacchi     return;
297*4d9fdb46SRobert Mustacchi }
298*4d9fdb46SRobert Mustacchi 
299*4d9fdb46SRobert Mustacchi /* load_macho_header32(dwarf_macho_object_access_internals_t *mfp)*/
300*4d9fdb46SRobert Mustacchi static int
load_macho_header32(dwarf_macho_object_access_internals_t * mfp,int * errcode)301*4d9fdb46SRobert Mustacchi load_macho_header32(dwarf_macho_object_access_internals_t *mfp, int *errcode)
302*4d9fdb46SRobert Mustacchi {
303*4d9fdb46SRobert Mustacchi     struct mach_header mh32;
304*4d9fdb46SRobert Mustacchi     int res = 0;
305*4d9fdb46SRobert Mustacchi 
306*4d9fdb46SRobert Mustacchi     if (sizeof(mh32) > mfp->mo_filesize) {
307*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_TOO_SMALL;
308*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
309*4d9fdb46SRobert Mustacchi     }
310*4d9fdb46SRobert Mustacchi     res = RRMOA(mfp->mo_fd, &mh32, 0, sizeof(mh32),
311*4d9fdb46SRobert Mustacchi         (off_t)mfp->mo_filesize, errcode);
312*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
313*4d9fdb46SRobert Mustacchi         return res;
314*4d9fdb46SRobert Mustacchi     }
315*4d9fdb46SRobert Mustacchi     /* Do not adjust endianness of magic, leave as-is. */
316*4d9fdb46SRobert Mustacchi     ASNAR(memcpy,mfp->mo_header.magic,mh32.magic);
317*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh32.cputype);
318*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh32.cpusubtype);
319*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh32.filetype);
320*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh32.ncmds);
321*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh32.sizeofcmds);
322*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh32.flags);
323*4d9fdb46SRobert Mustacchi     mfp->mo_header.reserved = 0;
324*4d9fdb46SRobert Mustacchi     mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds;
325*4d9fdb46SRobert Mustacchi     mfp->mo_command_start_offset = sizeof(mh32);
326*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
327*4d9fdb46SRobert Mustacchi }
328*4d9fdb46SRobert Mustacchi 
329*4d9fdb46SRobert Mustacchi /* load_macho_header64(dwarf_macho_object_access_internals_t *mfp) */
330*4d9fdb46SRobert Mustacchi static int
load_macho_header64(dwarf_macho_object_access_internals_t * mfp,int * errcode)331*4d9fdb46SRobert Mustacchi load_macho_header64(dwarf_macho_object_access_internals_t *mfp,
332*4d9fdb46SRobert Mustacchi     int *errcode)
333*4d9fdb46SRobert Mustacchi {
334*4d9fdb46SRobert Mustacchi     struct mach_header_64 mh64;
335*4d9fdb46SRobert Mustacchi     int res = 0;
336*4d9fdb46SRobert Mustacchi 
337*4d9fdb46SRobert Mustacchi     if (sizeof(mh64) > mfp->mo_filesize) {
338*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_TOO_SMALL;
339*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
340*4d9fdb46SRobert Mustacchi     }
341*4d9fdb46SRobert Mustacchi     res = RRMOA(mfp->mo_fd, &mh64, 0, sizeof(mh64),
342*4d9fdb46SRobert Mustacchi         (off_t)mfp->mo_filesize, errcode);
343*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
344*4d9fdb46SRobert Mustacchi         return res;
345*4d9fdb46SRobert Mustacchi     }
346*4d9fdb46SRobert Mustacchi     /* Do not adjust endianness of magic, leave as-is. */
347*4d9fdb46SRobert Mustacchi     ASNAR(memcpy,mfp->mo_header.magic,mh64.magic);
348*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.cputype,mh64.cputype);
349*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.cpusubtype,mh64.cpusubtype);
350*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.filetype,mh64.filetype);
351*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.ncmds,mh64.ncmds);
352*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.sizeofcmds,mh64.sizeofcmds);
353*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.flags,mh64.flags);
354*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,mfp->mo_header.reserved,mh64.reserved);
355*4d9fdb46SRobert Mustacchi     mfp->mo_command_count = (unsigned int)mfp->mo_header.ncmds;
356*4d9fdb46SRobert Mustacchi     mfp->mo_command_start_offset = sizeof(mh64);
357*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
358*4d9fdb46SRobert Mustacchi }
359*4d9fdb46SRobert Mustacchi 
360*4d9fdb46SRobert Mustacchi int
dwarf_load_macho_header(dwarf_macho_object_access_internals_t * mfp,int * errcode)361*4d9fdb46SRobert Mustacchi dwarf_load_macho_header(dwarf_macho_object_access_internals_t *mfp,
362*4d9fdb46SRobert Mustacchi     int *errcode)
363*4d9fdb46SRobert Mustacchi {
364*4d9fdb46SRobert Mustacchi     int res = 0;
365*4d9fdb46SRobert Mustacchi 
366*4d9fdb46SRobert Mustacchi     if (mfp->mo_offsetsize == 32) {
367*4d9fdb46SRobert Mustacchi         res = load_macho_header32(mfp,errcode);
368*4d9fdb46SRobert Mustacchi     } else if (mfp->mo_offsetsize == 64) {
369*4d9fdb46SRobert Mustacchi         res = load_macho_header64(mfp,errcode);
370*4d9fdb46SRobert Mustacchi     } else {
371*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
372*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
373*4d9fdb46SRobert Mustacchi     }
374*4d9fdb46SRobert Mustacchi     return res;
375*4d9fdb46SRobert Mustacchi }
376*4d9fdb46SRobert Mustacchi 
377*4d9fdb46SRobert Mustacchi 
378*4d9fdb46SRobert Mustacchi static int
load_segment_command_content32(dwarf_macho_object_access_internals_t * mfp,struct generic_macho_command * mmp,struct generic_macho_segment_command * msp,Dwarf_Unsigned mmpindex,int * errcode)379*4d9fdb46SRobert Mustacchi load_segment_command_content32(
380*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,
381*4d9fdb46SRobert Mustacchi     struct generic_macho_command *mmp,
382*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *msp,
383*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned mmpindex,
384*4d9fdb46SRobert Mustacchi     int *errcode)
385*4d9fdb46SRobert Mustacchi {
386*4d9fdb46SRobert Mustacchi     struct segment_command sc;
387*4d9fdb46SRobert Mustacchi     int res = 0;
388*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned filesize = mfp->mo_filesize;
389*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segoffset = mmp->offset_this_command;
390*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc);
391*4d9fdb46SRobert Mustacchi 
392*4d9fdb46SRobert Mustacchi     if (mmp->offset_this_command > filesize ||
393*4d9fdb46SRobert Mustacchi         mmp->cmdsize > filesize ||
394*4d9fdb46SRobert Mustacchi         (mmp->cmdsize + mmp->offset_this_command) > filesize ) {
395*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD;
396*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
397*4d9fdb46SRobert Mustacchi     }
398*4d9fdb46SRobert Mustacchi     res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc),
399*4d9fdb46SRobert Mustacchi         (off_t)filesize, errcode);
400*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
401*4d9fdb46SRobert Mustacchi         return res;
402*4d9fdb46SRobert Mustacchi     }
403*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd);
404*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize);
405*4d9fdb46SRobert Mustacchi     strncpy(msp->segname,sc.segname,16);
406*4d9fdb46SRobert Mustacchi     msp->segname[15] =0;
407*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr);
408*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize);
409*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff);
410*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize);
411*4d9fdb46SRobert Mustacchi     if (msp->fileoff > mfp->mo_filesize ||
412*4d9fdb46SRobert Mustacchi         msp->filesize > mfp->mo_filesize) {
413*4d9fdb46SRobert Mustacchi         /* corrupt */
414*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_OFFSET_BAD;
415*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
416*4d9fdb46SRobert Mustacchi     }
417*4d9fdb46SRobert Mustacchi     if ((msp->fileoff+msp->filesize ) > filesize) {
418*4d9fdb46SRobert Mustacchi         /* corrupt */
419*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_OFFSET_BAD;
420*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
421*4d9fdb46SRobert Mustacchi     }
422*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot);
423*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot);
424*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects);
425*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->flags,sc.flags);
426*4d9fdb46SRobert Mustacchi     msp->macho_command_index = mmpindex;
427*4d9fdb46SRobert Mustacchi     msp->sectionsoffset = afterseghdr;
428*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
429*4d9fdb46SRobert Mustacchi }
430*4d9fdb46SRobert Mustacchi static int
load_segment_command_content64(dwarf_macho_object_access_internals_t * mfp,struct generic_macho_command * mmp,struct generic_macho_segment_command * msp,Dwarf_Unsigned mmpindex,int * errcode)431*4d9fdb46SRobert Mustacchi load_segment_command_content64(
432*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,
433*4d9fdb46SRobert Mustacchi     struct generic_macho_command *mmp,
434*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *msp,
435*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned mmpindex,int *errcode)
436*4d9fdb46SRobert Mustacchi {
437*4d9fdb46SRobert Mustacchi     struct segment_command_64 sc;
438*4d9fdb46SRobert Mustacchi     int res = 0;
439*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned filesize = mfp->mo_filesize;
440*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segoffset = mmp->offset_this_command;
441*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned afterseghdr = segoffset + sizeof(sc);
442*4d9fdb46SRobert Mustacchi 
443*4d9fdb46SRobert Mustacchi     if (mmp->offset_this_command > filesize ||
444*4d9fdb46SRobert Mustacchi         mmp->cmdsize > filesize ||
445*4d9fdb46SRobert Mustacchi         (mmp->cmdsize + mmp->offset_this_command) > filesize ) {
446*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_OFFSET_BAD;
447*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
448*4d9fdb46SRobert Mustacchi     }
449*4d9fdb46SRobert Mustacchi     res = RRMOA(mfp->mo_fd, &sc, (off_t)mmp->offset_this_command, sizeof(sc),
450*4d9fdb46SRobert Mustacchi         (off_t)filesize, errcode);
451*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
452*4d9fdb46SRobert Mustacchi         return res;
453*4d9fdb46SRobert Mustacchi     }
454*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->cmd,sc.cmd);
455*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->cmdsize,sc.cmdsize);
456*4d9fdb46SRobert Mustacchi     strncpy(msp->segname,sc.segname,16);
457*4d9fdb46SRobert Mustacchi     msp->segname[16] =0;
458*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->vmaddr,sc.vmaddr);
459*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->vmsize,sc.vmsize);
460*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->fileoff,sc.fileoff);
461*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->filesize,sc.filesize);
462*4d9fdb46SRobert Mustacchi     if (msp->fileoff > filesize ||
463*4d9fdb46SRobert Mustacchi         msp->filesize > filesize) {
464*4d9fdb46SRobert Mustacchi         /* corrupt */
465*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_OFFSET_BAD;
466*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
467*4d9fdb46SRobert Mustacchi     }
468*4d9fdb46SRobert Mustacchi     if ((msp->fileoff+msp->filesize ) > filesize) {
469*4d9fdb46SRobert Mustacchi         /* corrupt */
470*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_OFFSET_BAD;
471*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
472*4d9fdb46SRobert Mustacchi     }
473*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->maxprot,sc.maxprot);
474*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->initprot,sc.initprot);
475*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->nsects,sc.nsects);
476*4d9fdb46SRobert Mustacchi     ASNAR(mfp->mo_copy_word,msp->flags,sc.flags);
477*4d9fdb46SRobert Mustacchi     msp->macho_command_index = mmpindex;
478*4d9fdb46SRobert Mustacchi     msp->sectionsoffset = afterseghdr;
479*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
480*4d9fdb46SRobert Mustacchi }
481*4d9fdb46SRobert Mustacchi 
482*4d9fdb46SRobert Mustacchi static int
dwarf_macho_load_segment_commands(dwarf_macho_object_access_internals_t * mfp,int * errcode)483*4d9fdb46SRobert Mustacchi dwarf_macho_load_segment_commands(
484*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,int *errcode)
485*4d9fdb46SRobert Mustacchi {
486*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i = 0;
487*4d9fdb46SRobert Mustacchi     struct generic_macho_command *mmp = 0;
488*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *msp = 0;
489*4d9fdb46SRobert Mustacchi 
490*4d9fdb46SRobert Mustacchi     if (mfp->mo_segment_count < 1) {
491*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
492*4d9fdb46SRobert Mustacchi     }
493*4d9fdb46SRobert Mustacchi     mfp->mo_segment_commands =
494*4d9fdb46SRobert Mustacchi         (struct generic_macho_segment_command *)
495*4d9fdb46SRobert Mustacchi         calloc(sizeof(struct generic_macho_segment_command),
496*4d9fdb46SRobert Mustacchi         (size_t)mfp->mo_segment_count);
497*4d9fdb46SRobert Mustacchi     if (!mfp->mo_segment_commands) {
498*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
499*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
500*4d9fdb46SRobert Mustacchi     }
501*4d9fdb46SRobert Mustacchi 
502*4d9fdb46SRobert Mustacchi     mmp = mfp->mo_commands;
503*4d9fdb46SRobert Mustacchi     msp = mfp->mo_segment_commands;
504*4d9fdb46SRobert Mustacchi     for (i = 0 ; i < mfp->mo_command_count; ++i,++mmp) {
505*4d9fdb46SRobert Mustacchi         unsigned cmd = (unsigned)mmp->cmd;
506*4d9fdb46SRobert Mustacchi         int res = 0;
507*4d9fdb46SRobert Mustacchi 
508*4d9fdb46SRobert Mustacchi         if (cmd == LC_SEGMENT) {
509*4d9fdb46SRobert Mustacchi             res = load_segment_command_content32(mfp,mmp,msp,i,errcode);
510*4d9fdb46SRobert Mustacchi             ++msp;
511*4d9fdb46SRobert Mustacchi         } else if (cmd == LC_SEGMENT_64) {
512*4d9fdb46SRobert Mustacchi             res = load_segment_command_content64(mfp,mmp,msp,i,errcode);
513*4d9fdb46SRobert Mustacchi             ++msp;
514*4d9fdb46SRobert Mustacchi         }
515*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
516*4d9fdb46SRobert Mustacchi             return res;
517*4d9fdb46SRobert Mustacchi         }
518*4d9fdb46SRobert Mustacchi     }
519*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
520*4d9fdb46SRobert Mustacchi }
521*4d9fdb46SRobert Mustacchi 
522*4d9fdb46SRobert Mustacchi static int
dwarf_macho_load_dwarf_section_details32(dwarf_macho_object_access_internals_t * mfp,struct generic_macho_segment_command * segp,Dwarf_Unsigned segi,int * errcode)523*4d9fdb46SRobert Mustacchi dwarf_macho_load_dwarf_section_details32(
524*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,
525*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *segp,
526*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segi, int *errcode)
527*4d9fdb46SRobert Mustacchi {
528*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned seci = 0;
529*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned seccount = segp->nsects;
530*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secalloc = seccount+1;
531*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned curoff = segp->sectionsoffset;
532*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned shdrlen = sizeof(struct section);
533*4d9fdb46SRobert Mustacchi 
534*4d9fdb46SRobert Mustacchi     struct generic_macho_section *secs = 0;
535*4d9fdb46SRobert Mustacchi 
536*4d9fdb46SRobert Mustacchi     secs = (struct generic_macho_section *)calloc(
537*4d9fdb46SRobert Mustacchi         sizeof(struct generic_macho_section),
538*4d9fdb46SRobert Mustacchi         (size_t)secalloc);
539*4d9fdb46SRobert Mustacchi     if (!secs) {
540*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
541*4d9fdb46SRobert Mustacchi         return DW_DLV_OK;
542*4d9fdb46SRobert Mustacchi     }
543*4d9fdb46SRobert Mustacchi     mfp->mo_dwarf_sections = secs;
544*4d9fdb46SRobert Mustacchi     mfp->mo_dwarf_sectioncount = secalloc;
545*4d9fdb46SRobert Mustacchi     if ((curoff  > mfp->mo_filesize) ||
546*4d9fdb46SRobert Mustacchi         (seccount > mfp->mo_filesize) ||
547*4d9fdb46SRobert Mustacchi         (curoff+(seccount*sizeof(struct section)) >
548*4d9fdb46SRobert Mustacchi             mfp->mo_filesize)) {
549*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_TOO_SMALL;
550*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
551*4d9fdb46SRobert Mustacchi     }
552*4d9fdb46SRobert Mustacchi     secs->offset_of_sec_rec = curoff;
553*4d9fdb46SRobert Mustacchi     /*  Leave 0 section all zeros except our offset,
554*4d9fdb46SRobert Mustacchi         elf-like in a sense */
555*4d9fdb46SRobert Mustacchi     secs->dwarfsectname = "";
556*4d9fdb46SRobert Mustacchi     ++secs;
557*4d9fdb46SRobert Mustacchi     seci = 1;
558*4d9fdb46SRobert Mustacchi     for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) {
559*4d9fdb46SRobert Mustacchi         struct section mosec;
560*4d9fdb46SRobert Mustacchi         int res = 0;
561*4d9fdb46SRobert Mustacchi 
562*4d9fdb46SRobert Mustacchi         res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec),
563*4d9fdb46SRobert Mustacchi             (off_t)mfp->mo_filesize, errcode);
564*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
565*4d9fdb46SRobert Mustacchi             return res;
566*4d9fdb46SRobert Mustacchi         }
567*4d9fdb46SRobert Mustacchi         strncpy(secs->sectname,mosec.sectname,16);
568*4d9fdb46SRobert Mustacchi         secs->sectname[16] = 0;
569*4d9fdb46SRobert Mustacchi         strncpy(secs->segname,mosec.segname,16);
570*4d9fdb46SRobert Mustacchi         secs->segname[16] = 0;
571*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr);
572*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->size,mosec.size);
573*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset);
574*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->align,mosec.align);
575*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff);
576*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc);
577*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags);
578*4d9fdb46SRobert Mustacchi         if (secs->offset > mfp->mo_filesize ||
579*4d9fdb46SRobert Mustacchi             secs->size > mfp->mo_filesize ||
580*4d9fdb46SRobert Mustacchi             (secs->offset+secs->size) > mfp->mo_filesize) {
581*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
582*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
583*4d9fdb46SRobert Mustacchi         }
584*4d9fdb46SRobert Mustacchi         secs->reserved1 = 0;
585*4d9fdb46SRobert Mustacchi         secs->reserved2 = 0;
586*4d9fdb46SRobert Mustacchi         secs->reserved3 = 0;
587*4d9fdb46SRobert Mustacchi         secs->generic_segment_num  = segi;
588*4d9fdb46SRobert Mustacchi         secs->offset_of_sec_rec = curoff;
589*4d9fdb46SRobert Mustacchi     }
590*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
591*4d9fdb46SRobert Mustacchi }
592*4d9fdb46SRobert Mustacchi static int
dwarf_macho_load_dwarf_section_details64(dwarf_macho_object_access_internals_t * mfp,struct generic_macho_segment_command * segp,Dwarf_Unsigned segi,int * errcode)593*4d9fdb46SRobert Mustacchi dwarf_macho_load_dwarf_section_details64(
594*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,
595*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *segp,
596*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segi,
597*4d9fdb46SRobert Mustacchi     int *errcode)
598*4d9fdb46SRobert Mustacchi {
599*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned seci = 0;
600*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned seccount = segp->nsects;
601*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned secalloc = seccount+1;
602*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned curoff = segp->sectionsoffset;
603*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned shdrlen = sizeof(struct section_64);
604*4d9fdb46SRobert Mustacchi     struct generic_macho_section *secs = 0;
605*4d9fdb46SRobert Mustacchi 
606*4d9fdb46SRobert Mustacchi     secs = (struct generic_macho_section *)calloc(
607*4d9fdb46SRobert Mustacchi         sizeof(struct generic_macho_section),
608*4d9fdb46SRobert Mustacchi         (size_t)secalloc);
609*4d9fdb46SRobert Mustacchi     if (!secs) {
610*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
611*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
612*4d9fdb46SRobert Mustacchi     }
613*4d9fdb46SRobert Mustacchi     mfp->mo_dwarf_sections = secs;
614*4d9fdb46SRobert Mustacchi     mfp->mo_dwarf_sectioncount = secalloc;
615*4d9fdb46SRobert Mustacchi     secs->offset_of_sec_rec = curoff;
616*4d9fdb46SRobert Mustacchi     /*  Leave 0 section all zeros except our offset,
617*4d9fdb46SRobert Mustacchi         elf-like in a sense */
618*4d9fdb46SRobert Mustacchi     secs->dwarfsectname = "";
619*4d9fdb46SRobert Mustacchi     ++secs;
620*4d9fdb46SRobert Mustacchi     if ((curoff  > mfp->mo_filesize) ||
621*4d9fdb46SRobert Mustacchi         (seccount > mfp->mo_filesize) ||
622*4d9fdb46SRobert Mustacchi         (curoff+(seccount*sizeof(struct section_64)) >
623*4d9fdb46SRobert Mustacchi             mfp->mo_filesize)) {
624*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_FILE_TOO_SMALL;
625*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
626*4d9fdb46SRobert Mustacchi     }
627*4d9fdb46SRobert Mustacchi     seci = 1;
628*4d9fdb46SRobert Mustacchi     for (; seci < secalloc; ++seci,++secs,curoff += shdrlen ) {
629*4d9fdb46SRobert Mustacchi         int res = 0;
630*4d9fdb46SRobert Mustacchi         struct section_64 mosec;
631*4d9fdb46SRobert Mustacchi 
632*4d9fdb46SRobert Mustacchi         res = RRMOA(mfp->mo_fd, &mosec, (off_t)curoff, sizeof(mosec),
633*4d9fdb46SRobert Mustacchi             (off_t)mfp->mo_filesize, errcode);
634*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
635*4d9fdb46SRobert Mustacchi             return res;
636*4d9fdb46SRobert Mustacchi         }
637*4d9fdb46SRobert Mustacchi         strncpy(secs->sectname,mosec.sectname,16);
638*4d9fdb46SRobert Mustacchi         secs->sectname[16] = 0;
639*4d9fdb46SRobert Mustacchi         strncpy(secs->segname,mosec.segname,16);
640*4d9fdb46SRobert Mustacchi         secs->segname[16] = 0;
641*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->addr,mosec.addr);
642*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->size,mosec.size);
643*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->offset,mosec.offset);
644*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->align,mosec.align);
645*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->reloff,mosec.reloff);
646*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->nreloc,mosec.nreloc);
647*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,secs->flags,mosec.flags);
648*4d9fdb46SRobert Mustacchi         if (secs->offset > mfp->mo_filesize ||
649*4d9fdb46SRobert Mustacchi             secs->size > mfp->mo_filesize ||
650*4d9fdb46SRobert Mustacchi             (secs->offset+secs->size) > mfp->mo_filesize) {
651*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
652*4d9fdb46SRobert Mustacchi             return DW_DLV_OK;
653*4d9fdb46SRobert Mustacchi         }
654*4d9fdb46SRobert Mustacchi         secs->reserved1 = 0;
655*4d9fdb46SRobert Mustacchi         secs->reserved2 = 0;
656*4d9fdb46SRobert Mustacchi         secs->reserved3 = 0;
657*4d9fdb46SRobert Mustacchi         secs->offset_of_sec_rec = curoff;
658*4d9fdb46SRobert Mustacchi         secs->generic_segment_num  = segi;
659*4d9fdb46SRobert Mustacchi     }
660*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
661*4d9fdb46SRobert Mustacchi }
662*4d9fdb46SRobert Mustacchi 
663*4d9fdb46SRobert Mustacchi static int
dwarf_macho_load_dwarf_section_details(dwarf_macho_object_access_internals_t * mfp,struct generic_macho_segment_command * segp,Dwarf_Unsigned segi,int * errcode)664*4d9fdb46SRobert Mustacchi dwarf_macho_load_dwarf_section_details(
665*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,
666*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *segp,
667*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segi,int *errcode)
668*4d9fdb46SRobert Mustacchi {
669*4d9fdb46SRobert Mustacchi     int res = 0;
670*4d9fdb46SRobert Mustacchi 
671*4d9fdb46SRobert Mustacchi     if (mfp->mo_offsetsize == 32) {
672*4d9fdb46SRobert Mustacchi         res = dwarf_macho_load_dwarf_section_details32(mfp,
673*4d9fdb46SRobert Mustacchi             segp,segi,errcode);
674*4d9fdb46SRobert Mustacchi     } else if (mfp->mo_offsetsize == 64) {
675*4d9fdb46SRobert Mustacchi         res = dwarf_macho_load_dwarf_section_details64(mfp,
676*4d9fdb46SRobert Mustacchi             segp,segi,errcode);
677*4d9fdb46SRobert Mustacchi     } else {
678*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_OFFSET_SIZE;
679*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
680*4d9fdb46SRobert Mustacchi     }
681*4d9fdb46SRobert Mustacchi     return res;
682*4d9fdb46SRobert Mustacchi }
683*4d9fdb46SRobert Mustacchi 
684*4d9fdb46SRobert Mustacchi static int
dwarf_macho_load_dwarf_sections(dwarf_macho_object_access_internals_t * mfp,int * errcode)685*4d9fdb46SRobert Mustacchi dwarf_macho_load_dwarf_sections(
686*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,int *errcode)
687*4d9fdb46SRobert Mustacchi {
688*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned segi = 0;
689*4d9fdb46SRobert Mustacchi 
690*4d9fdb46SRobert Mustacchi     struct generic_macho_segment_command *segp =
691*4d9fdb46SRobert Mustacchi         mfp->mo_segment_commands;
692*4d9fdb46SRobert Mustacchi     for ( ; segi < mfp->mo_segment_count; ++segi,++segp) {
693*4d9fdb46SRobert Mustacchi         int res = 0;
694*4d9fdb46SRobert Mustacchi 
695*4d9fdb46SRobert Mustacchi         if (strcmp(segp->segname,"__DWARF")) {
696*4d9fdb46SRobert Mustacchi             continue;
697*4d9fdb46SRobert Mustacchi         }
698*4d9fdb46SRobert Mustacchi         /* Found DWARF, for now assume only one such. */
699*4d9fdb46SRobert Mustacchi         res = dwarf_macho_load_dwarf_section_details(mfp,segp,segi,errcode);
700*4d9fdb46SRobert Mustacchi         return res;
701*4d9fdb46SRobert Mustacchi     }
702*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
703*4d9fdb46SRobert Mustacchi }
704*4d9fdb46SRobert Mustacchi 
705*4d9fdb46SRobert Mustacchi /* Works the same, 32 or 64 bit */
706*4d9fdb46SRobert Mustacchi int
dwarf_load_macho_commands(dwarf_macho_object_access_internals_t * mfp,int * errcode)707*4d9fdb46SRobert Mustacchi dwarf_load_macho_commands(
708*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *mfp,int *errcode)
709*4d9fdb46SRobert Mustacchi {
710*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cmdi = 0;
711*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned curoff = mfp->mo_command_start_offset;
712*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned cmdspace = 0;
713*4d9fdb46SRobert Mustacchi     struct load_command mc;
714*4d9fdb46SRobert Mustacchi     struct generic_macho_command *mcp = 0;
715*4d9fdb46SRobert Mustacchi     unsigned segment_command_count = 0;
716*4d9fdb46SRobert Mustacchi     int res = 0;
717*4d9fdb46SRobert Mustacchi 
718*4d9fdb46SRobert Mustacchi     if (mfp->mo_command_count >= mfp->mo_filesize) {
719*4d9fdb46SRobert Mustacchi         /* corrupt object. */
720*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD;
721*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
722*4d9fdb46SRobert Mustacchi     }
723*4d9fdb46SRobert Mustacchi     if ((curoff + mfp->mo_command_count * sizeof(mc)) >=
724*4d9fdb46SRobert Mustacchi         mfp->mo_filesize) {
725*4d9fdb46SRobert Mustacchi         /* corrupt object. */
726*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_MACH_O_SEGOFFSET_BAD;
727*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
728*4d9fdb46SRobert Mustacchi     }
729*4d9fdb46SRobert Mustacchi 
730*4d9fdb46SRobert Mustacchi     mfp->mo_commands = (struct generic_macho_command *) calloc(
731*4d9fdb46SRobert Mustacchi         mfp->mo_command_count,sizeof(struct generic_macho_command));
732*4d9fdb46SRobert Mustacchi     if( !mfp->mo_commands) {
733*4d9fdb46SRobert Mustacchi         /* out of memory */
734*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
735*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
736*4d9fdb46SRobert Mustacchi     }
737*4d9fdb46SRobert Mustacchi     mcp = mfp->mo_commands;
738*4d9fdb46SRobert Mustacchi     for ( ; cmdi < mfp->mo_header.ncmds; ++cmdi,++mcp ) {
739*4d9fdb46SRobert Mustacchi         res = RRMOA(mfp->mo_fd, &mc, (off_t)curoff, sizeof(mc),
740*4d9fdb46SRobert Mustacchi             (off_t)mfp->mo_filesize, errcode);
741*4d9fdb46SRobert Mustacchi         if (res != DW_DLV_OK) {
742*4d9fdb46SRobert Mustacchi             return res;
743*4d9fdb46SRobert Mustacchi         }
744*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,mcp->cmd,mc.cmd);
745*4d9fdb46SRobert Mustacchi         ASNAR(mfp->mo_copy_word,mcp->cmdsize,mc.cmdsize);
746*4d9fdb46SRobert Mustacchi         mcp->offset_this_command = curoff;
747*4d9fdb46SRobert Mustacchi         curoff += mcp->cmdsize;
748*4d9fdb46SRobert Mustacchi         cmdspace += mcp->cmdsize;
749*4d9fdb46SRobert Mustacchi         if (mcp->cmdsize > mfp->mo_filesize ||
750*4d9fdb46SRobert Mustacchi             curoff > mfp->mo_filesize) {
751*4d9fdb46SRobert Mustacchi             /* corrupt object */
752*4d9fdb46SRobert Mustacchi             *errcode = DW_DLE_FILE_OFFSET_BAD;
753*4d9fdb46SRobert Mustacchi             return DW_DLV_ERROR;
754*4d9fdb46SRobert Mustacchi         }
755*4d9fdb46SRobert Mustacchi         if (mcp->cmd == LC_SEGMENT || mcp->cmd == LC_SEGMENT_64) {
756*4d9fdb46SRobert Mustacchi             segment_command_count++;
757*4d9fdb46SRobert Mustacchi         }
758*4d9fdb46SRobert Mustacchi     }
759*4d9fdb46SRobert Mustacchi     mfp->mo_segment_count = segment_command_count;
760*4d9fdb46SRobert Mustacchi     res = dwarf_macho_load_segment_commands(mfp,errcode);
761*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
762*4d9fdb46SRobert Mustacchi         return res;
763*4d9fdb46SRobert Mustacchi     }
764*4d9fdb46SRobert Mustacchi     res = dwarf_macho_load_dwarf_sections(mfp,errcode);
765*4d9fdb46SRobert Mustacchi     return res;
766*4d9fdb46SRobert Mustacchi }
767*4d9fdb46SRobert Mustacchi int
_dwarf_macho_setup(int fd,char * true_path,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,Dwarf_Unsigned access,unsigned groupnumber,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * dbg,Dwarf_Error * error)768*4d9fdb46SRobert Mustacchi _dwarf_macho_setup(int fd,
769*4d9fdb46SRobert Mustacchi     char *true_path,
770*4d9fdb46SRobert Mustacchi     unsigned ftype,
771*4d9fdb46SRobert Mustacchi     unsigned endian,
772*4d9fdb46SRobert Mustacchi     unsigned offsetsize,
773*4d9fdb46SRobert Mustacchi     size_t filesize,
774*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned access,
775*4d9fdb46SRobert Mustacchi     unsigned groupnumber,
776*4d9fdb46SRobert Mustacchi     Dwarf_Handler errhand,
777*4d9fdb46SRobert Mustacchi     Dwarf_Ptr errarg,
778*4d9fdb46SRobert Mustacchi     Dwarf_Debug *dbg,Dwarf_Error *error)
779*4d9fdb46SRobert Mustacchi {
780*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Interface *binary_interface = 0;
781*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *intfc = 0;
782*4d9fdb46SRobert Mustacchi     int res = DW_DLV_OK;
783*4d9fdb46SRobert Mustacchi     int localerrnum = 0;
784*4d9fdb46SRobert Mustacchi 
785*4d9fdb46SRobert Mustacchi     res = _dwarf_macho_object_access_init(
786*4d9fdb46SRobert Mustacchi         fd,
787*4d9fdb46SRobert Mustacchi         ftype,endian,offsetsize,filesize,access,
788*4d9fdb46SRobert Mustacchi         &binary_interface,
789*4d9fdb46SRobert Mustacchi         &localerrnum);
790*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
791*4d9fdb46SRobert Mustacchi         if (res == DW_DLV_NO_ENTRY) {
792*4d9fdb46SRobert Mustacchi             return res;
793*4d9fdb46SRobert Mustacchi         }
794*4d9fdb46SRobert Mustacchi         _dwarf_error(NULL, error, localerrnum);
795*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
796*4d9fdb46SRobert Mustacchi     }
797*4d9fdb46SRobert Mustacchi     /*  allocates and initializes Dwarf_Debug,
798*4d9fdb46SRobert Mustacchi         generic code */
799*4d9fdb46SRobert Mustacchi     res = dwarf_object_init_b(binary_interface, errhand, errarg,
800*4d9fdb46SRobert Mustacchi         groupnumber, dbg, error);
801*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
802*4d9fdb46SRobert Mustacchi         _dwarf_destruct_macho_access(binary_interface);
803*4d9fdb46SRobert Mustacchi         return res;
804*4d9fdb46SRobert Mustacchi     }
805*4d9fdb46SRobert Mustacchi     intfc = binary_interface->object;
806*4d9fdb46SRobert Mustacchi     intfc->mo_path = strdup(true_path);
807*4d9fdb46SRobert Mustacchi     return res;
808*4d9fdb46SRobert Mustacchi }
809*4d9fdb46SRobert Mustacchi 
810*4d9fdb46SRobert Mustacchi 
811*4d9fdb46SRobert Mustacchi static Dwarf_Obj_Access_Methods const macho_methods = {
812*4d9fdb46SRobert Mustacchi     macho_get_section_info,
813*4d9fdb46SRobert Mustacchi     macho_get_byte_order,
814*4d9fdb46SRobert Mustacchi     macho_get_length_size,
815*4d9fdb46SRobert Mustacchi     macho_get_pointer_size,
816*4d9fdb46SRobert Mustacchi     macho_get_section_count,
817*4d9fdb46SRobert Mustacchi     macho_load_section,
818*4d9fdb46SRobert Mustacchi     /*  We do not do macho relocations. dsym files do not require it. */
819*4d9fdb46SRobert Mustacchi     NULL
820*4d9fdb46SRobert Mustacchi };
821*4d9fdb46SRobert Mustacchi 
822*4d9fdb46SRobert Mustacchi /*  On any error this frees internals argument. */
823*4d9fdb46SRobert Mustacchi static int
_dwarf_macho_object_access_internals_init(dwarf_macho_object_access_internals_t * internals,int fd,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,UNUSEDARG Dwarf_Unsigned access,int * errcode)824*4d9fdb46SRobert Mustacchi _dwarf_macho_object_access_internals_init(
825*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t * internals,
826*4d9fdb46SRobert Mustacchi     int  fd,
827*4d9fdb46SRobert Mustacchi     unsigned ftype,
828*4d9fdb46SRobert Mustacchi     unsigned endian,
829*4d9fdb46SRobert Mustacchi     unsigned offsetsize,
830*4d9fdb46SRobert Mustacchi     size_t filesize,
831*4d9fdb46SRobert Mustacchi     UNUSEDARG Dwarf_Unsigned access,
832*4d9fdb46SRobert Mustacchi     int *errcode)
833*4d9fdb46SRobert Mustacchi {
834*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t * intfc = internals;
835*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned i  = 0;
836*4d9fdb46SRobert Mustacchi     struct generic_macho_section *sp = 0;
837*4d9fdb46SRobert Mustacchi     struct Dwarf_Obj_Access_Interface_s *localdoas;
838*4d9fdb46SRobert Mustacchi     int res = 0;
839*4d9fdb46SRobert Mustacchi 
840*4d9fdb46SRobert Mustacchi     /*  Must malloc as _dwarf_destruct_macho_access()
841*4d9fdb46SRobert Mustacchi         forces that due to other uses. */
842*4d9fdb46SRobert Mustacchi     localdoas = (struct Dwarf_Obj_Access_Interface_s *)
843*4d9fdb46SRobert Mustacchi         malloc(sizeof(struct Dwarf_Obj_Access_Interface_s));
844*4d9fdb46SRobert Mustacchi     if (!localdoas) {
845*4d9fdb46SRobert Mustacchi         free(internals);
846*4d9fdb46SRobert Mustacchi         *errcode = DW_DLE_ALLOC_FAIL;
847*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
848*4d9fdb46SRobert Mustacchi     }
849*4d9fdb46SRobert Mustacchi     memset(localdoas,0,sizeof(struct Dwarf_Obj_Access_Interface_s));
850*4d9fdb46SRobert Mustacchi     intfc->mo_ident[0]    = 'M';
851*4d9fdb46SRobert Mustacchi     intfc->mo_ident[1]    = '1';
852*4d9fdb46SRobert Mustacchi     intfc->mo_fd          = fd;
853*4d9fdb46SRobert Mustacchi     intfc->mo_is_64bit    = ((offsetsize==64)?TRUE:FALSE);
854*4d9fdb46SRobert Mustacchi     intfc->mo_offsetsize  = offsetsize;
855*4d9fdb46SRobert Mustacchi     intfc->mo_pointersize = offsetsize;
856*4d9fdb46SRobert Mustacchi     intfc->mo_filesize    = filesize;
857*4d9fdb46SRobert Mustacchi     intfc->mo_ftype       = ftype;
858*4d9fdb46SRobert Mustacchi 
859*4d9fdb46SRobert Mustacchi #ifdef WORDS_BIGENDIAN
860*4d9fdb46SRobert Mustacchi     if (endian == DW_ENDIAN_LITTLE ) {
861*4d9fdb46SRobert Mustacchi         intfc->mo_copy_word = _dwarf_memcpy_swap_bytes;
862*4d9fdb46SRobert Mustacchi         intfc->mo_endian = DW_OBJECT_LSB;
863*4d9fdb46SRobert Mustacchi     } else {
864*4d9fdb46SRobert Mustacchi         intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes;
865*4d9fdb46SRobert Mustacchi         intfc->mo_endian = DW_OBJECT_MSB;
866*4d9fdb46SRobert Mustacchi     }
867*4d9fdb46SRobert Mustacchi #else  /* LITTLE ENDIAN */
868*4d9fdb46SRobert Mustacchi     if (endian == DW_ENDIAN_LITTLE ) {
869*4d9fdb46SRobert Mustacchi         intfc->mo_copy_word = _dwarf_memcpy_noswap_bytes;
870*4d9fdb46SRobert Mustacchi         intfc->mo_endian = DW_OBJECT_LSB;
871*4d9fdb46SRobert Mustacchi     } else {
872*4d9fdb46SRobert Mustacchi         intfc->mo_copy_word = _dwarf_memcpy_swap_bytes;
873*4d9fdb46SRobert Mustacchi         intfc->mo_endian = DW_OBJECT_MSB;
874*4d9fdb46SRobert Mustacchi     }
875*4d9fdb46SRobert Mustacchi #endif /* LITTLE- BIG-ENDIAN */
876*4d9fdb46SRobert Mustacchi     res = dwarf_load_macho_header(intfc,errcode);
877*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
878*4d9fdb46SRobert Mustacchi         localdoas->object = intfc;
879*4d9fdb46SRobert Mustacchi         localdoas->methods = 0;
880*4d9fdb46SRobert Mustacchi         _dwarf_destruct_macho_access(localdoas);
881*4d9fdb46SRobert Mustacchi         return res;
882*4d9fdb46SRobert Mustacchi     }
883*4d9fdb46SRobert Mustacchi     /* Load sections */
884*4d9fdb46SRobert Mustacchi     res = dwarf_load_macho_commands(intfc,errcode);
885*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK) {
886*4d9fdb46SRobert Mustacchi         localdoas->methods = 0;
887*4d9fdb46SRobert Mustacchi         localdoas->object = intfc;
888*4d9fdb46SRobert Mustacchi         _dwarf_destruct_macho_access(localdoas);
889*4d9fdb46SRobert Mustacchi         return res;
890*4d9fdb46SRobert Mustacchi     }
891*4d9fdb46SRobert Mustacchi     sp = intfc->mo_dwarf_sections+1;
892*4d9fdb46SRobert Mustacchi     for(i = 1; i < intfc->mo_dwarf_sectioncount ; ++i,++sp) {
893*4d9fdb46SRobert Mustacchi         int j = 1;
894*4d9fdb46SRobert Mustacchi         int lim = sizeof(SectionNames)/sizeof(SectionNames[0]);
895*4d9fdb46SRobert Mustacchi         sp->dwarfsectname = "";
896*4d9fdb46SRobert Mustacchi         for( ; j < lim; ++j) {
897*4d9fdb46SRobert Mustacchi             if(!strcmp(sp->sectname,SectionNames[j].ms_moname)) {
898*4d9fdb46SRobert Mustacchi                 sp->dwarfsectname = SectionNames[j].ms_dwname;
899*4d9fdb46SRobert Mustacchi                 break;
900*4d9fdb46SRobert Mustacchi             }
901*4d9fdb46SRobert Mustacchi         }
902*4d9fdb46SRobert Mustacchi     }
903*4d9fdb46SRobert Mustacchi     free(localdoas);
904*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
905*4d9fdb46SRobert Mustacchi }
906*4d9fdb46SRobert Mustacchi 
907*4d9fdb46SRobert Mustacchi 
908*4d9fdb46SRobert Mustacchi static int
_dwarf_macho_object_access_init(int fd,unsigned ftype,unsigned endian,unsigned offsetsize,size_t filesize,Dwarf_Unsigned access,Dwarf_Obj_Access_Interface ** binary_interface,int * localerrnum)909*4d9fdb46SRobert Mustacchi _dwarf_macho_object_access_init(
910*4d9fdb46SRobert Mustacchi     int  fd,
911*4d9fdb46SRobert Mustacchi     unsigned ftype,
912*4d9fdb46SRobert Mustacchi     unsigned endian,
913*4d9fdb46SRobert Mustacchi     unsigned offsetsize,
914*4d9fdb46SRobert Mustacchi     size_t filesize,
915*4d9fdb46SRobert Mustacchi     Dwarf_Unsigned access,
916*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Interface **binary_interface,
917*4d9fdb46SRobert Mustacchi     int *localerrnum)
918*4d9fdb46SRobert Mustacchi {
919*4d9fdb46SRobert Mustacchi 
920*4d9fdb46SRobert Mustacchi     int res = 0;
921*4d9fdb46SRobert Mustacchi     dwarf_macho_object_access_internals_t *internals = 0;
922*4d9fdb46SRobert Mustacchi     Dwarf_Obj_Access_Interface *intfc = 0;
923*4d9fdb46SRobert Mustacchi 
924*4d9fdb46SRobert Mustacchi     internals = malloc(sizeof(dwarf_macho_object_access_internals_t));
925*4d9fdb46SRobert Mustacchi     if (!internals) {
926*4d9fdb46SRobert Mustacchi         *localerrnum = DW_DLE_ALLOC_FAIL;
927*4d9fdb46SRobert Mustacchi         /* Impossible case, we hope. Give up. */
928*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
929*4d9fdb46SRobert Mustacchi     }
930*4d9fdb46SRobert Mustacchi     memset(internals,0,sizeof(*internals));
931*4d9fdb46SRobert Mustacchi     res = _dwarf_macho_object_access_internals_init(internals,
932*4d9fdb46SRobert Mustacchi         fd,
933*4d9fdb46SRobert Mustacchi         ftype, endian, offsetsize, filesize,
934*4d9fdb46SRobert Mustacchi         access,
935*4d9fdb46SRobert Mustacchi         localerrnum);
936*4d9fdb46SRobert Mustacchi     if (res != DW_DLV_OK){
937*4d9fdb46SRobert Mustacchi         /* *err is already set and the call freed internals. */
938*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
939*4d9fdb46SRobert Mustacchi     }
940*4d9fdb46SRobert Mustacchi 
941*4d9fdb46SRobert Mustacchi     intfc = malloc(sizeof(Dwarf_Obj_Access_Interface));
942*4d9fdb46SRobert Mustacchi     if (!intfc) {
943*4d9fdb46SRobert Mustacchi         /* Impossible case, we hope. Give up. */
944*4d9fdb46SRobert Mustacchi         free(internals);
945*4d9fdb46SRobert Mustacchi         *localerrnum = DW_DLE_ALLOC_FAIL;
946*4d9fdb46SRobert Mustacchi         return DW_DLV_ERROR;
947*4d9fdb46SRobert Mustacchi     }
948*4d9fdb46SRobert Mustacchi     /* Initialize the interface struct */
949*4d9fdb46SRobert Mustacchi     intfc->object = internals;
950*4d9fdb46SRobert Mustacchi     intfc->methods = &macho_methods;
951*4d9fdb46SRobert Mustacchi     *binary_interface = intfc;
952*4d9fdb46SRobert Mustacchi     return DW_DLV_OK;
953*4d9fdb46SRobert Mustacchi }
954