1 /* 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.oracle.ipack.macho; 27 28 import com.oracle.ipack.util.Util; 29 import java.io.DataInput; 30 import java.io.DataOutput; 31 import java.io.IOException; 32 import java.util.ArrayList; 33 34 public final class SegmentCommand extends MachoCommand { 35 private final ArrayList<Section> sections; 36 37 private String segmentName; 38 private int vmAddress; 39 private int vmSize; 40 private int fileOffset; 41 private int fileSize; 42 private int maxVmProtection; 43 private int initVmProtection; 44 private int flags; 45 46 public SegmentCommand() { 47 sections = new ArrayList<Section>(); 48 } 49 50 @Override 51 public int getId() { 52 return LC_SEGMENT; 53 } 54 55 public Section findSection(final String sectionName) { 56 for (final Section section: sections) { 57 if (sectionName.equals(section.getSectionName())) { 58 return section; 59 } 60 } 61 62 return null; 63 } 64 65 public String getSegmentName() { 66 return segmentName; 67 } 68 69 public void setSegmentName(final String segmentName) { 70 this.segmentName = segmentName; 71 } 72 73 public int getVmAddress() { 74 return vmAddress; 75 } 76 77 public void setVmAddress(final int vmAddress) { 78 this.vmAddress = vmAddress; 79 } 80 81 public int getVmSize() { 82 return vmSize; 83 } 84 85 public void setVmSize(final int vmSize) { 86 this.vmSize = vmSize; 87 } 88 89 public int getFileOffset() { 90 return fileOffset; 91 } 92 93 public void setFileOffset(final int fileOffset) { 94 this.fileOffset = fileOffset; 95 } 96 97 public int getFileSize() { 98 return fileSize; 99 } 100 101 public void setFileSize(final int fileSize) { 102 this.fileSize = fileSize; 103 } 104 105 public int getMaxVmProtection() { 106 return maxVmProtection; 107 } 108 109 public void setMaxVmProtection(final int maxVmProtection) { 110 this.maxVmProtection = maxVmProtection; 111 } 112 113 public int getInitVmProtection() { 114 return initVmProtection; 115 } 116 117 public void setInitVmProtection(final int initVmProtection) { 118 this.initVmProtection = initVmProtection; 119 } 120 121 public int getFlags() { 122 return flags; 123 } 124 125 public void setFlags(final int flags) { 126 this.flags = flags; 127 } 128 129 @Override 130 public String toString() { 131 return "SegmentCommand { segmentName: \"" + segmentName + "\"" 132 + ", vmAddress: 0x" + Util.hex32(vmAddress) 133 + ", vmSize: 0x" + Util.hex32(vmSize) 134 + ", fileOffset: 0x" + Util.hex32(fileOffset) 135 + ", fileSize: 0x" + Util.hex32(fileSize) 136 + ", maxVmProtection: " + maxVmProtection 137 + ", initVmProtection: " + initVmProtection 138 + ", flags: 0x" + Util.hex32(flags) 139 + ", sections: " + sections + " }"; 140 } 141 142 @Override 143 protected int getPayloadSize() { 144 return 16 + 4 * 8 + 68 * sections.size(); 145 } 146 147 @Override 148 protected void readPayload(final DataInput dataInput) throws IOException { 149 segmentName = Util.readString(dataInput, 16).trim(); 150 vmAddress = dataInput.readInt(); 151 vmSize = dataInput.readInt(); 152 fileOffset = dataInput.readInt(); 153 fileSize = dataInput.readInt(); 154 maxVmProtection = dataInput.readInt(); 155 initVmProtection = dataInput.readInt(); 156 final int numberOfSections = dataInput.readInt(); 157 flags = dataInput.readInt(); 158 159 sections.clear(); 160 sections.ensureCapacity(numberOfSections); 161 for (int i = 0; i < numberOfSections; ++i) { 162 final Section section = new Section(); 163 section.readImpl(dataInput); 164 sections.add(section); 165 } 166 } 167 168 @Override 169 protected void writePayload(final DataOutput dataOutput) 170 throws IOException { 171 Util.writeString(dataOutput, segmentName, 16, '\0'); 172 dataOutput.writeInt(vmAddress); 173 dataOutput.writeInt(vmSize); 174 dataOutput.writeInt(fileOffset); 175 dataOutput.writeInt(fileSize); 176 dataOutput.writeInt(maxVmProtection); 177 dataOutput.writeInt(initVmProtection); 178 dataOutput.writeInt(sections.size()); 179 dataOutput.writeInt(flags); 180 181 for (final Section section: sections) { 182 section.write(dataOutput); 183 } 184 } 185 186 public static final class Section { 187 private String sectionName; 188 private String segmentName; 189 private int address; 190 private int size; 191 private int offset; 192 private int align; 193 private int relocationOffset; 194 private int numberOfRelocations; 195 private int flags; 196 private int reserved1; 197 private int reserved2; 198 199 public String getSectionName() { 200 return sectionName; 201 } 202 203 public void setSectionName(final String sectionName) { 204 this.sectionName = sectionName; 205 } 206 207 public String getSegmentName() { 208 return segmentName; 209 } 210 211 public void setSegmentName(final String segmentName) { 212 this.segmentName = segmentName; 213 } 214 215 public int getAddress() { 216 return address; 217 } 218 219 public void setAddress(final int address) { 220 this.address = address; 221 } 222 223 public int getSize() { 224 return size; 225 } 226 227 public void setSize(final int size) { 228 this.size = size; 229 } 230 231 public int getOffset() { 232 return offset; 233 } 234 235 public void setOffset(final int offset) { 236 this.offset = offset; 237 } 238 239 public int getAlign() { 240 return align; 241 } 242 243 public void setAlign(final int align) { 244 this.align = align; 245 } 246 247 public int getRelocationOffset() { 248 return relocationOffset; 249 } 250 251 public void setRelocationOffset(final int relocationOffset) { 252 this.relocationOffset = relocationOffset; 253 } 254 255 public int getNumberOfRelocations() { 256 return numberOfRelocations; 257 } 258 259 public void setNumberOfRelocations(final int numberOfRelocations) { 260 this.numberOfRelocations = numberOfRelocations; 261 } 262 263 public int getFlags() { 264 return flags; 265 } 266 267 public void setFlags(final int flags) { 268 this.flags = flags; 269 } 270 271 public int getReserved1() { 272 return reserved1; 273 } 274 275 public void setReserved1(final int reserved1) { 276 this.reserved1 = reserved1; 277 } 278 279 public int getReserved2() { 280 return reserved2; 281 } 282 283 public void setReserved2(final int reserved2) { 284 this.reserved2 = reserved2; 285 } 286 287 public void write(final DataOutput dataOutput) throws IOException { 288 Util.writeString(dataOutput, sectionName, 16, '\0'); 289 Util.writeString(dataOutput, segmentName, 16, '\0'); 290 dataOutput.writeInt(address); 291 dataOutput.writeInt(size); 292 dataOutput.writeInt(offset); 293 dataOutput.writeInt(align); 294 dataOutput.writeInt(relocationOffset); 295 dataOutput.writeInt(numberOfRelocations); 296 dataOutput.writeInt(flags); 297 dataOutput.writeInt(reserved1); 298 dataOutput.writeInt(reserved2); 299 } 300 301 private void readImpl(final DataInput dataInput) throws IOException { 302 sectionName = Util.readString(dataInput, 16).trim(); 303 segmentName = Util.readString(dataInput, 16).trim(); 304 address = dataInput.readInt(); 305 size = dataInput.readInt(); 306 offset = dataInput.readInt(); 307 align = dataInput.readInt(); 308 relocationOffset = dataInput.readInt(); 309 numberOfRelocations = dataInput.readInt(); 310 flags = dataInput.readInt(); 311 reserved1 = dataInput.readInt(); 312 reserved2 = dataInput.readInt(); 313 } 314 315 @Override 316 public String toString() { 317 return "Section { sectionName: \"" + sectionName + "\"" 318 + ", segmentName: \"" + segmentName + "\"" 319 + ", address: 0x" + Util.hex32(address) 320 + ", size: 0x" + Util.hex32(size) 321 + ", offset: 0x" + Util.hex32(offset) 322 + ", align: " + align 323 + ", relocationOffset: 0x" 324 + Util.hex32(relocationOffset) 325 + ", numberOfRelocations: " + numberOfRelocations 326 + ", flags: 0x" + Util.hex32(flags) 327 + ", reserved1: " + reserved1 328 + ", reserved2: " + reserved2 + " }"; 329 } 330 } 331 }