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.dx.dex.file; 18 19 import com.android.dx.dex.DexFormat; 20 import com.android.dx.dex.SizeOf; 21 import com.android.dx.rop.cst.CstString; 22 import com.android.dx.util.AnnotatedOutput; 23 import com.android.dx.util.Hex; 24 25 /** 26 * File header section of a {@code .dex} file. 27 */ 28 public final class HeaderItem extends IndexedItem { 29 /** 30 * Constructs an instance. 31 */ HeaderItem()32 public HeaderItem() { 33 // This space intentionally left blank. 34 } 35 36 /** {@inheritDoc} */ 37 @Override itemType()38 public ItemType itemType() { 39 return ItemType.TYPE_HEADER_ITEM; 40 } 41 42 /** {@inheritDoc} */ 43 @Override writeSize()44 public int writeSize() { 45 return SizeOf.HEADER_ITEM; 46 } 47 48 /** {@inheritDoc} */ 49 @Override addContents(DexFile file)50 public void addContents(DexFile file) { 51 // Nothing to do here. 52 } 53 54 /** {@inheritDoc} */ 55 @Override writeTo(DexFile file, AnnotatedOutput out)56 public void writeTo(DexFile file, AnnotatedOutput out) { 57 int mapOff = file.getMap().getFileOffset(); 58 Section firstDataSection = file.getFirstDataSection(); 59 Section lastDataSection = file.getLastDataSection(); 60 int dataOff = firstDataSection.getFileOffset(); 61 int dataSize = lastDataSection.getFileOffset() + 62 lastDataSection.writeSize() - dataOff; 63 64 String magic = file.getDexOptions().getMagic(); 65 66 if (out.annotates()) { 67 out.annotate(8, "magic: " + new CstString(magic).toQuoted()); 68 out.annotate(4, "checksum"); 69 out.annotate(20, "signature"); 70 out.annotate(4, "file_size: " + 71 Hex.u4(file.getFileSize())); 72 out.annotate(4, "header_size: " + Hex.u4(SizeOf.HEADER_ITEM)); 73 out.annotate(4, "endian_tag: " + Hex.u4(DexFormat.ENDIAN_TAG)); 74 out.annotate(4, "link_size: 0"); 75 out.annotate(4, "link_off: 0"); 76 out.annotate(4, "map_off: " + Hex.u4(mapOff)); 77 } 78 79 // Write the magic number. 80 for (int i = 0; i < 8; i++) { 81 out.writeByte(magic.charAt(i)); 82 } 83 84 // Leave space for the checksum and signature. 85 out.writeZeroes(24); 86 87 out.writeInt(file.getFileSize()); 88 out.writeInt(SizeOf.HEADER_ITEM); 89 out.writeInt(DexFormat.ENDIAN_TAG); 90 91 /* 92 * Write zeroes for the link size and data, as the output 93 * isn't a staticly linked file. 94 */ 95 out.writeZeroes(8); 96 97 out.writeInt(mapOff); 98 99 // Write out each section's respective header part. 100 file.getStringIds().writeHeaderPart(out); 101 file.getTypeIds().writeHeaderPart(out); 102 file.getProtoIds().writeHeaderPart(out); 103 file.getFieldIds().writeHeaderPart(out); 104 file.getMethodIds().writeHeaderPart(out); 105 file.getClassDefs().writeHeaderPart(out); 106 107 if (out.annotates()) { 108 out.annotate(4, "data_size: " + Hex.u4(dataSize)); 109 out.annotate(4, "data_off: " + Hex.u4(dataOff)); 110 } 111 112 out.writeInt(dataSize); 113 out.writeInt(dataOff); 114 } 115 } 116