1/*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#include <string.h>
24#include "stuff/ofile.h"
25
26/*
27 * ofile_get_word() gets a 32 bit word for the address in the object file.
28 */
29__private_extern__
30int32_t
31ofile_get_word(
32uint64_t addr,
33uint32_t *word,
34void *get_word_data /* struct mach_object_file *ofile */ )
35{
36    uint32_t i, j;
37    struct load_command *lc;
38    struct segment_command *sg;
39    struct section *s;
40    struct segment_command_64 *sg64;
41    struct section_64 *s64;
42    struct ofile *ofile;
43
44	ofile = (struct ofile *)get_word_data;
45	for(i = 0, lc = ofile->load_commands; i < ofile->mh->ncmds; i++){
46	    if(lc->cmd == LC_SEGMENT){
47		sg = (struct segment_command *)lc;
48		s = (struct section *)
49		    ((char *)sg + sizeof(struct segment_command));
50		for(j = 0 ; j < sg->nsects ; j++){
51		    if(addr >= s->addr && addr < s->addr + s->size){
52			if(s->flags == S_ZEROFILL ||
53			   s->flags == S_THREAD_LOCAL_ZEROFILL)
54			    *word = 0;
55			else {
56			    if(s->offset > ofile->object_size ||
57			       s->offset + s->size > ofile->object_size ||
58			       s->offset % sizeof(uint32_t) != 0 ||
59			       (addr - s->addr) % sizeof(uint32_t) != 0)
60				return(-1);
61			    else{
62				memcpy(word, (ofile->object_addr +
63					       (s->offset + addr - s->addr)),
64					sizeof(uint32_t));
65				if(ofile->object_byte_sex !=get_host_byte_sex())
66				    *word = SWAP_INT(*word);
67			    }
68			}
69			return(0);
70		    }
71		    s++;
72		}
73	    }
74	    else if(lc->cmd == LC_SEGMENT_64){
75		sg64 = (struct segment_command_64 *)lc;
76		s64 = (struct section_64 *)
77		    ((char *)sg64 + sizeof(struct segment_command_64));
78		for(j = 0 ; j < sg64->nsects ; j++){
79		    if(addr >= s64->addr && addr < s64->addr + s64->size){
80			if(s64->flags == S_ZEROFILL ||
81			   s64->flags == S_THREAD_LOCAL_ZEROFILL)
82			    *word = 0;
83			else {
84			    if(s64->offset > ofile->object_size ||
85			       s64->offset + s64->size > ofile->object_size ||
86			       s64->offset % sizeof(uint32_t) != 0 ||
87			       (addr - s64->addr) % sizeof(uint32_t) != 0)
88				return(-1);
89			    else{
90				memcpy(word, (ofile->object_addr +
91					      (s64->offset + addr - s64->addr)),
92					sizeof(uint32_t));
93				if(ofile->object_byte_sex !=get_host_byte_sex())
94				    *word = SWAP_INT(*word);
95			    }
96			}
97			return(0);
98		    }
99		    s64++;
100		}
101	    }
102	    lc = (struct load_command *)((char *)lc + lc->cmdsize);
103	}
104	return(-1);
105}
106