1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.dexgen.dex.file; 18 19 import com.android.dexgen.rop.cst.CstUtf8; 20 import com.android.dexgen.util.AnnotatedOutput; 21 import com.android.dexgen.util.Hex; 22 23 /** 24 * File header section of a {@code .dex} file. 25 */ 26 public final class HeaderItem extends IndexedItem { 27 /** 28 * {@code non-null;} the file format magic number, represented as the 29 * low-order bytes of a string 30 */ 31 private static final String MAGIC = "dex\n035\0"; 32 33 /** size of this section, in bytes */ 34 private static final int HEADER_SIZE = 0x70; 35 36 /** the endianness tag */ 37 private static final int ENDIAN_TAG = 0x12345678; 38 39 /** 40 * Constructs an instance. 41 */ HeaderItem()42 public HeaderItem() { 43 // This space intentionally left blank. 44 } 45 46 /** {@inheritDoc} */ 47 @Override itemType()48 public ItemType itemType() { 49 return ItemType.TYPE_HEADER_ITEM; 50 } 51 52 /** {@inheritDoc} */ 53 @Override writeSize()54 public int writeSize() { 55 return HEADER_SIZE; 56 } 57 58 /** {@inheritDoc} */ 59 @Override addContents(DexFile file)60 public void addContents(DexFile file) { 61 // Nothing to do here. 62 } 63 64 /** {@inheritDoc} */ 65 @Override writeTo(DexFile file, AnnotatedOutput out)66 public void writeTo(DexFile file, AnnotatedOutput out) { 67 int mapOff = file.getMap().getFileOffset(); 68 Section firstDataSection = file.getFirstDataSection(); 69 Section lastDataSection = file.getLastDataSection(); 70 int dataOff = firstDataSection.getFileOffset(); 71 int dataSize = lastDataSection.getFileOffset() + 72 lastDataSection.writeSize() - dataOff; 73 74 if (out.annotates()) { 75 out.annotate(8, "magic: " + new CstUtf8(MAGIC).toQuoted()); 76 out.annotate(4, "checksum"); 77 out.annotate(20, "signature"); 78 out.annotate(4, "file_size: " + 79 Hex.u4(file.getFileSize())); 80 out.annotate(4, "header_size: " + Hex.u4(HEADER_SIZE)); 81 out.annotate(4, "endian_tag: " + Hex.u4(ENDIAN_TAG)); 82 out.annotate(4, "link_size: 0"); 83 out.annotate(4, "link_off: 0"); 84 out.annotate(4, "map_off: " + Hex.u4(mapOff)); 85 } 86 87 // Write the magic number. 88 for (int i = 0; i < 8; i++) { 89 out.writeByte(MAGIC.charAt(i)); 90 } 91 92 // Leave space for the checksum and signature. 93 out.writeZeroes(24); 94 95 out.writeInt(file.getFileSize()); 96 out.writeInt(HEADER_SIZE); 97 out.writeInt(ENDIAN_TAG); 98 99 /* 100 * Write zeroes for the link size and data, as the output 101 * isn't a staticly linked file. 102 */ 103 out.writeZeroes(8); 104 105 out.writeInt(mapOff); 106 107 // Write out each section's respective header part. 108 file.getStringIds().writeHeaderPart(out); 109 file.getTypeIds().writeHeaderPart(out); 110 file.getProtoIds().writeHeaderPart(out); 111 file.getFieldIds().writeHeaderPart(out); 112 file.getMethodIds().writeHeaderPart(out); 113 file.getClassDefs().writeHeaderPart(out); 114 115 if (out.annotates()) { 116 out.annotate(4, "data_size: " + Hex.u4(dataSize)); 117 out.annotate(4, "data_off: " + Hex.u4(dataOff)); 118 } 119 120 out.writeInt(dataSize); 121 out.writeInt(dataOff); 122 } 123 } 124