1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/*
2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project
3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License");
5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License.
6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at
7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *      http://www.apache.org/licenses/LICENSE-2.0
9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul *
10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software
11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS,
12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and
14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License.
15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.dex.file;
18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstUtf8;
20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.AnnotatedOutput;
21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.Hex;
22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/**
24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * File header section of a {@code .dex} file.
25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */
26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class HeaderItem extends IndexedItem {
27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * {@code non-null;} the file format magic number, represented as the
29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * low-order bytes of a string
30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final String MAGIC = "dex\n035\0";
32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** size of this section, in bytes */
34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final int HEADER_SIZE = 0x70;
35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** the endianness tag */
37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    private static final int ENDIAN_TAG = 0x12345678;
38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /**
40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     * Constructs an instance.
41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul     */
42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public HeaderItem() {
43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // This space intentionally left blank.
44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public ItemType itemType() {
49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return ItemType.TYPE_HEADER_ITEM;
50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public int writeSize() {
55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        return HEADER_SIZE;
56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void addContents(DexFile file) {
61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // Nothing to do here.
62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    /** {@inheritDoc} */
65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    @Override
66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    public void writeTo(DexFile file, AnnotatedOutput out) {
67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int mapOff = file.getMap().getFileOffset();
68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Section firstDataSection = file.getFirstDataSection();
69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        Section lastDataSection = file.getLastDataSection();
70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int dataOff = firstDataSection.getFileOffset();
71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        int dataSize = lastDataSection.getFileOffset() +
72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            lastDataSection.writeSize() - dataOff;
73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (out.annotates()) {
75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(8, "magic: " + new CstUtf8(MAGIC).toQuoted());
76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "checksum");
77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(20, "signature");
78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "file_size:       " +
79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul                         Hex.u4(file.getFileSize()));
80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "header_size:     " + Hex.u4(HEADER_SIZE));
81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "endian_tag:      " + Hex.u4(ENDIAN_TAG));
82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "link_size:       0");
83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "link_off:        0");
84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "map_off:         " + Hex.u4(mapOff));
85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // Write the magic number.
88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        for (int i = 0; i < 8; i++) {
89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.writeByte(MAGIC.charAt(i));
90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // Leave space for the checksum and signature.
93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeZeroes(24);
94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(file.getFileSize());
96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(HEADER_SIZE);
97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(ENDIAN_TAG);
98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        /*
100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         * Write zeroes for the link size and data, as the output
101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         * isn't a staticly linked file.
102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul         */
103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeZeroes(8);
104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(mapOff);
106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        // Write out each section's respective header part.
108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getStringIds().writeHeaderPart(out);
109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getTypeIds().writeHeaderPart(out);
110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getProtoIds().writeHeaderPart(out);
111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getFieldIds().writeHeaderPart(out);
112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getMethodIds().writeHeaderPart(out);
113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        file.getClassDefs().writeHeaderPart(out);
114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        if (out.annotates()) {
116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "data_size:       " + Hex.u4(dataSize));
117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul            out.annotate(4, "data_off:        " + Hex.u4(dataOff));
118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        }
119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul
120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(dataSize);
121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul        out.writeInt(dataOff);
122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul    }
123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul}
124