xref: /aosp_15_r20/external/bazelbuild-rules_android/src/tools/ak/mindex/mindex.go (revision 9e965d6fece27a77de5377433c2f7e6999b8cc0b)
1// Copyright 2018 The Bazel Authors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package mindex writes a minimal dex into a file.
16// It encodes the minimal necessary fields to pass muster with the android runtime.
17package mindex
18
19import (
20	"flag"
21	"io/ioutil"
22	"log"
23	"sync"
24
25	"src/tools/ak/types"
26)
27
28var (
29	// Cmd defines the command to run mindex
30	Cmd = types.Command{
31		Init: Init,
32		Run:  Run,
33		Desc: desc,
34		Flags: []string{
35			"out",
36		},
37	}
38
39	// Variables that hold flag values
40	out      string
41	initOnce sync.Once
42
43	// see https://android.googlesource.com/platform/art/+/android-5.0.1_r1/runtime/dex_file.h
44
45	minDex = []byte{
46		0x64, 0x65, 0x78, 0x0A, // 0x00: Dex magic
47		0x30, 0x33, 0x35, 0x00, // 0x04: Dex version
48		0x44, 0x0E, 0xC1, 0x0F, // 0x08: Adler32 checksum
49		0x8B, 0x9B, 0x61, 0xEA, // 0x0C: Sha1 digest
50		0xC1, 0x7F, 0x94, 0x5A, // 0x10: Sha1 digest cont.
51		0xE9, 0xC0, 0x8A, 0x70, // 0x14: Sha1 digest cont.
52		0xFD, 0xED, 0x4F, 0x53, // 0x18: Sha1 digest cont.
53		0x0F, 0x10, 0x51, 0x75, // 0x1C: Sha1 digest cont.
54
55		// Header
56		0x8C, 0x00, 0x00, 0x00, // 0x20: Files size
57		0x70, 0x00, 0x00, 0x00, // 0x24: Header size
58		0x78, 0x56, 0x34, 0x12, // 0x28: Endian tag
59		0x00, 0x00, 0x00, 0x00, // 0x2C: Link size
60		0x00, 0x00, 0x00, 0x00, // 0x30: Link offset
61		0x70, 0x00, 0x00, 0x00, // 0x34: Map offset
62		0x00, 0x00, 0x00, 0x00, // 0x38: String ids size
63		0x00, 0x00, 0x00, 0x00, // 0x3C: String ids offset
64		0x00, 0x00, 0x00, 0x00, // 0x40: Type ids size
65		0x00, 0x00, 0x00, 0x00, // 0x44: Type ids offset
66		0x00, 0x00, 0x00, 0x00, // 0x48: Proto ids size
67		0x00, 0x00, 0x00, 0x00, // 0x4C: Proto ids offset
68		0x00, 0x00, 0x00, 0x00, // 0x50: Field ids size
69		0x00, 0x00, 0x00, 0x00, // 0x54: Field ids offset
70		0x00, 0x00, 0x00, 0x00, // 0x58: Method ids size
71		0x00, 0x00, 0x00, 0x00, // 0x5C: Method ids offset
72		0x00, 0x00, 0x00, 0x00, // 0x60: Class defs size
73		0x00, 0x00, 0x00, 0x00, // 0x64: Class defs offset
74		0x1C, 0x00, 0x00, 0x00, // 0x68: Data size
75		0x70, 0x00, 0x00, 0x00, // 0x6C: Data offset
76
77		// Data
78		0x02, 0x00, 0x00, 0x00, // 0x70: Map list size (header and map list)
79		0x00, 0x00, 0x00, 0x00, // 0x74: kDexTypeHeaderItem
80		0x01, 0x00, 0x00, 0x00, // 0x78: HeaderItem count
81		0x00, 0x00, 0x00, 0x00, // 0x7C: Offset 0x00
82		0x00, 0x10, 0x00, 0x00, // 0x80: kDexTypeMapList
83		0x01, 0x00, 0x00, 0x00, // 0x84: MapList count
84		0x70, 0x00, 0x00, 0x00, // 0x88: Offset 0x70
85	}
86)
87
88// Init initializes mindex.
89func Init() {
90	initOnce.Do(func() {
91		flag.StringVar(&out, "out", "", "Path to output.")
92	})
93}
94
95func desc() string {
96	return "Mindex writes the smallest possible dex to a file."
97}
98
99// Run is the entry point for mindex.
100func Run() {
101	if out == "" {
102		log.Fatal("Flags -out must be specified.")
103	}
104
105	if err := ioutil.WriteFile(out, minDex, 0655); err != nil {
106		log.Fatalf("Error writing minimal dex %v", err)
107	}
108}
109