1 /**
2  * Copyright: Copyright (c) 2010 Jacob Carlborg. All rights reserved.
3  * Authors: Jacob Carlborg
4  * Version: Initial created: Feb 23, 2010
5  * License: BSD style: $(LICENSE)
6  */
7 module rt.compiler.dmd.darwin.Image;
8 
9 version (darwin):
10 
11 import rt.compiler.dmd.darwin.dyld;
12 import rt.compiler.dmd.darwin.loader;
13 import rt.compiler.dmd.darwin.getsect;
14 
15 struct Image
16 {
17 	private mach_header* header_;
18 	private uint index_;
19 	
20 	static Image opCall (uint index)
21 	{
22 		Image image;
23 		image.header_ = _dyld_get_image_header(index);
24 		image.index_ = index;
25 		
26 		return image;
27 	}
28 	
29 	static uint numberOfImages ()
30 	{
31 		return _dyld_image_count;
32 	}
33 	
34 	static int opApply (int delegate(ref Image) dg)
35 	{
36 		int result;
37 		
38 		for (size_t i = 0; i < numberOfImages; i++)
39 		{
40 			result = dg(Image(i));
41 			
42 			if (result)
43 				break;
44 		}
45 		
46 		return result;
47 	}
48 	
49 	static int opApplyReverse (int delegate(ref Image) dg)
50 	{
51 		int result;
52 		
53 		for (int i = numberOfImages - 1; i >= 0; i--)
54 		{
55 			result = dg(Image(i));
56 			
57 			if (result)
58 				break;
59 		}
60 		
61 		return result;
62 	}
63 	
64 	mach_header* header ()
65 	{
66 		return header_;
67 	}
68 	
69 	mach_header_64* header64 ()
70 	{
71 		return cast(mach_header_64*) header_;
72 	}
73 	
74 	CPU cpu ()
75 	{
76 		return CPU(header_);
77 	}
78 }
79 
80 struct CPU
81 {
82 	private mach_header* header;
83 	
84 	static CPU opCall (mach_header* header)
85 	{
86 		CPU cpu;
87 		cpu.header = header;
88 		
89 		return cpu;
90 	}
91 	
92 	bool is32bit ()
93 	{		
94 		return (header.magic & MH_MAGIC) != 0;
95 	}
96 
97 	bool is64bit ()
98 	{
99 		return (header.magic & MH_MAGIC_64) != 0;
100 	}
101 }
102 
103 T[] getSectionData (T, char[] segmentName, char[] sectionName) ()
104 {
105     T[] array;
106     
107     const c_segmentName = segmentName.ptr;
108     const c_sectionName = sectionName.ptr;    
109     
110     void* start;
111     void* end;
112     
113     foreach_reverse (image ; Image)
114     {            
115         if (image.cpu.is32bit)
116         {
117             auto header = image.header;
118             section* sect = getsectbynamefromheader(header, c_segmentName, c_sectionName);
119             
120             if (sect is null || sect.size == 0)
121                 continue;
122 
123             start = cast(void*) (cast(byte*) header + sect.offset);
124     	    end = cast(void*) (cast(byte*) start + sect.size);
125         }
126         
127         else
128         {
129             auto header = image.header64;
130             section_64* sect = getsectbynamefromheader_64(header, c_segmentName, c_sectionName);
131             
132             if (sect is null || sect.size == 0)
133                 continue;
134 
135             start = cast(void*) (cast(byte*) header + sect.offset);
136     	    end = cast(void*) (cast(byte*) start + sect.size);
137         }
138 	    
139 	    size_t len = cast(T*)end - cast(T*)start;
140 		array ~= (cast(T*)start)[0 .. len];
141     }
142     
143     return array;
144 }