/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.dexgen.dex.file;
import com.android.dexgen.rop.cst.CstUtf8;
import com.android.dexgen.util.AnnotatedOutput;
import com.android.dexgen.util.Hex;
/**
* File header section of a {@code .dex} file.
*/
public final class HeaderItem extends IndexedItem {
/**
* {@code non-null;} the file format magic number, represented as the
* low-order bytes of a string
*/
private static final String MAGIC = "dex\n035\0";
/** size of this section, in bytes */
private static final int HEADER_SIZE = 0x70;
/** the endianness tag */
private static final int ENDIAN_TAG = 0x12345678;
/**
* Constructs an instance.
*/
public HeaderItem() {
// This space intentionally left blank.
}
/** {@inheritDoc} */
@Override
public ItemType itemType() {
return ItemType.TYPE_HEADER_ITEM;
}
/** {@inheritDoc} */
@Override
public int writeSize() {
return HEADER_SIZE;
}
/** {@inheritDoc} */
@Override
public void addContents(DexFile file) {
// Nothing to do here.
}
/** {@inheritDoc} */
@Override
public void writeTo(DexFile file, AnnotatedOutput out) {
int mapOff = file.getMap().getFileOffset();
Section firstDataSection = file.getFirstDataSection();
Section lastDataSection = file.getLastDataSection();
int dataOff = firstDataSection.getFileOffset();
int dataSize = lastDataSection.getFileOffset() +
lastDataSection.writeSize() - dataOff;
if (out.annotates()) {
out.annotate(8, "magic: " + new CstUtf8(MAGIC).toQuoted());
out.annotate(4, "checksum");
out.annotate(20, "signature");
out.annotate(4, "file_size: " +
Hex.u4(file.getFileSize()));
out.annotate(4, "header_size: " + Hex.u4(HEADER_SIZE));
out.annotate(4, "endian_tag: " + Hex.u4(ENDIAN_TAG));
out.annotate(4, "link_size: 0");
out.annotate(4, "link_off: 0");
out.annotate(4, "map_off: " + Hex.u4(mapOff));
}
// Write the magic number.
for (int i = 0; i < 8; i++) {
out.writeByte(MAGIC.charAt(i));
}
// Leave space for the checksum and signature.
out.writeZeroes(24);
out.writeInt(file.getFileSize());
out.writeInt(HEADER_SIZE);
out.writeInt(ENDIAN_TAG);
/*
* Write zeroes for the link size and data, as the output
* isn't a staticly linked file.
*/
out.writeZeroes(8);
out.writeInt(mapOff);
// Write out each section's respective header part.
file.getStringIds().writeHeaderPart(out);
file.getTypeIds().writeHeaderPart(out);
file.getProtoIds().writeHeaderPart(out);
file.getFieldIds().writeHeaderPart(out);
file.getMethodIds().writeHeaderPart(out);
file.getClassDefs().writeHeaderPart(out);
if (out.annotates()) {
out.annotate(4, "data_size: " + Hex.u4(dataSize));
out.annotate(4, "data_off: " + Hex.u4(dataOff));
}
out.writeInt(dataSize);
out.writeInt(dataOff);
}
}
|