blob: 5a715e54e37b4cc42b33babdfff29da80cec4397 [file] [log] [blame]
Nick Kledzikabb69812012-05-31 22:34:00 +00001//===- lib/ReaderWriter/Native/NativeFileFormat.h -------------------------===//
Nick Kledzik55fd6be2012-01-16 22:03:44 +00002//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Nick Kledzikabb69812012-05-31 22:34:00 +000010#ifndef LLD_READER_WRITER_NATIVE_FILE_FORMAT_H_
11#define LLD_READER_WRITER_NATIVE_FILE_FORMAT_H_
Nick Kledzik55fd6be2012-01-16 22:03:44 +000012
Michael J. Spencer9f91f952012-03-09 05:27:11 +000013#include "llvm/Support/DataTypes.h"
Nick Kledzik55fd6be2012-01-16 22:03:44 +000014
15namespace lld {
16
17
18//
19// Overview:
20//
21// The number one design goal of this file format is enable the linker to
Michael J. Spencer765792d2012-04-03 18:40:27 +000022// read object files into in-memory Atom objects extremely quickly.
23// The second design goal is to enable future modifications to the
24// Atom attribute model.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000025//
Michael J. Spencer765792d2012-04-03 18:40:27 +000026// The llvm native object file format is not like traditional object file
Nick Kledzik55fd6be2012-01-16 22:03:44 +000027// formats (e.g. ELF, COFF, mach-o). There is no symbol table and no
Michael J. Spencer765792d2012-04-03 18:40:27 +000028// sections. Instead the file is essentially an array of archived Atoms.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000029// It is *not* serialized Atoms which would require deserialization into
30// in memory objects. Instead it is an array of read-only info about each
31// Atom. The NativeReader bulk creates in-memory Atoms which just have
32// an ivar which points to the read-only info for that Atom. No additional
33// processing is done to construct the in-memory Atoms. All Atom attribute
Michael J. Spencer765792d2012-04-03 18:40:27 +000034// getter methods are virtual calls which dig up the info they need from the
Nick Kledzik55fd6be2012-01-16 22:03:44 +000035// ivar data.
Michael J. Spencer765792d2012-04-03 18:40:27 +000036//
Nick Kledzik55fd6be2012-01-16 22:03:44 +000037// To support the gradual evolution of Atom attributes, the Atom read-only
38// data is versioned. The NativeReader chooses which in-memory Atom class
39// to use based on the version. What this means is that if new attributes
40// are added (or changed) in the Atom model, a new native atom class and
41// read-only atom info struct needs to be defined. Then, all the existing
42// native reader atom classes need to be modified to do their best effort
43// to map their old style read-only data to the new Atom model. At some point
Michael J. Spencer765792d2012-04-03 18:40:27 +000044// some classes to support old versions may be dropped.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000045//
46//
47// Details:
48//
Michael J. Spencer765792d2012-04-03 18:40:27 +000049// The native object file format consists of a header that specifies the
Nick Kledzik55fd6be2012-01-16 22:03:44 +000050// endianness of the file and the architecture along with a list of "chunks"
51// in the file. A Chunk is simply a tagged range of the file. There is
Michael J. Spencer765792d2012-04-03 18:40:27 +000052// one chunk for the array of atom infos. There is another chunk for the
53// string pool, and another for the content pool.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000054//
55// It turns out there most atoms have very similar sets of attributes, only
56// the name and content attribute vary. To exploit this fact to reduce the file
57// size, the atom read-only info contains just the name and content info plus
58// a reference to which attribute set it uses. The attribute sets are stored
59// in another chunk.
60//
61
62
63//
64// An entry in the NativeFileHeader that describes one chunk of the file.
65//
66struct NativeChunk {
67 uint32_t signature;
68 uint32_t fileOffset;
69 uint32_t fileSize;
70 uint32_t elementCount;
71};
72
73
74//
75// The header in a native object file
76//
77struct NativeFileHeader {
78 uint8_t magic[16];
79 uint32_t endian;
80 uint32_t architecture;
81 uint32_t fileSize;
82 uint32_t chunkCount;
Nick Kledzik49d6cc82012-02-15 00:38:09 +000083 // NativeChunk chunks[]
Nick Kledzik55fd6be2012-01-16 22:03:44 +000084};
85
86//
87// Possible values for NativeChunk.signature field
88//
89enum NativeChunkSignatures {
90 NCS_DefinedAtomsV1 = 1,
91 NCS_AttributesArrayV1 = 2,
Sid Manning2a590242012-10-18 17:16:19 +000092 NCS_AbsoluteAttributesV1 = 12,
Nick Kledzik23384e82012-02-07 02:59:54 +000093 NCS_UndefinedAtomsV1 = 3,
Nick Kledzik6bc04c62012-02-22 21:56:59 +000094 NCS_SharedLibraryAtomsV1 = 4,
95 NCS_AbsoluteAtomsV1 = 5,
96 NCS_Strings = 6,
97 NCS_ReferencesArrayV1 = 7,
98 NCS_ReferencesArrayV2 = 8,
99 NCS_TargetsTable = 9,
100 NCS_AddendsTable = 10,
101 NCS_Content = 11,
Michael J. Spencer765792d2012-04-03 18:40:27 +0000102};
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000103
104//
105// The 16-bytes at the start of a native object file
106//
107#define NATIVE_FILE_HEADER_MAGIC "llvm nat obj v1 "
108
109//
110// Possible values for the NativeFileHeader.endian field
111//
112enum {
113 NFH_BigEndian = 0x42696745,
114 NFH_LittleEndian = 0x4574696c
115};
116
117
118//
119// Possible values for the NativeFileHeader.architecture field
120//
121enum {
122 NFA_x86 = 1,
123 NFA_x86_64 = 2,
124 NFA_armv6 = 3,
125 NFA_armv7 = 4,
126};
127
128
129//
130// The NCS_DefinedAtomsV1 chunk contains an array of these structs
131//
132struct NativeDefinedAtomIvarsV1 {
133 uint32_t nameOffset;
134 uint32_t attributesOffset;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000135 uint32_t referencesStartIndex;
136 uint32_t referencesCount;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000137 uint32_t contentOffset;
138 uint32_t contentSize;
139};
140
141
142//
143// The NCS_AttributesArrayV1 chunk contains an array of these structs
144//
145struct NativeAtomAttributesV1 {
146 uint32_t sectionNameOffset;
147 uint16_t align2;
148 uint16_t alignModulus;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000149 uint8_t scope;
150 uint8_t interposable;
151 uint8_t merge;
152 uint8_t contentType;
Nick Kledzik36293f62013-01-23 22:32:56 +0000153 uint8_t sectionChoiceAndPosition; // high nibble is choice, low is position
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000154 uint8_t deadStrip;
155 uint8_t permissions;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000156 uint8_t alias;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000157};
158
159
160
Nick Kledzik23384e82012-02-07 02:59:54 +0000161//
162// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
163//
164struct NativeUndefinedAtomIvarsV1 {
165 uint32_t nameOffset;
166 uint32_t flags;
167};
168
169
170
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000171//
172// The NCS_SharedLibraryAtomsV1 chunk contains an array of these structs
173//
174struct NativeSharedLibraryAtomIvarsV1 {
175 uint32_t nameOffset;
176 uint32_t loadNameOffset;
177 uint32_t flags;
178};
179
180
181
182//
183// The NCS_AbsoluteAtomsV1 chunk contains an array of these structs
184//
185struct NativeAbsoluteAtomIvarsV1 {
186 uint32_t nameOffset;
Sid Manning2a590242012-10-18 17:16:19 +0000187 uint32_t attributesOffset;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000188 uint32_t reserved;
189 uint64_t value;
190};
191
192
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000193
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000194//
195// The NCS_ReferencesArrayV1 chunk contains an array of these structs
196//
197struct NativeReferenceIvarsV1 {
Nick Kledzikb334be12012-04-07 01:31:00 +0000198 enum {
199 noTarget = 0xFFFF
200 };
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000201 uint16_t offsetInAtom;
202 int16_t kind;
203 uint16_t targetIndex;
204 uint16_t addendIndex;
205};
206
207
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000208//
209// The NCS_ReferencesArrayV2 chunk contains an array of these structs
210//
211struct NativeReferenceIvarsV2 {
212 uint64_t offsetInAtom;
213 int64_t addend;
214 int32_t kind;
215 uint32_t targetIndex;
216};
217
218
219//
220// The NCS_TargetsTable chunk contains an array of uint32_t entries.
Michael J. Spencer765792d2012-04-03 18:40:27 +0000221// The C++ class Reference has a target() method that returns a
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000222// pointer to another Atom. We can't have pointers in object files,
223// so instead NativeReferenceIvarsV1 contains an index to the target.
Michael J. Spencer765792d2012-04-03 18:40:27 +0000224// The index is into this NCS_TargetsTable of uint32_t entries.
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000225// The values in this table are the index of the (target) atom in this file.
226// For DefinedAtoms the value is from 0 to NCS_DefinedAtomsV1.elementCount.
227// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to
228// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.
229//
230
231
232//
233// The NCS_AddendsTable chunk contains an array of int64_t entries.
234// If we allocated space for addends directly in NativeReferenceIvarsV1
235// it would double the size of that struct. But since addends are rare,
236// we instead just keep a pool of addends and have NativeReferenceIvarsV1
Michael J. Spencer765792d2012-04-03 18:40:27 +0000237// (if it needs an addend) just store the index (into the pool) of the
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000238// addend it needs.
239//
240
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000241
242
243} // namespace lld
244
Nick Kledzikabb69812012-05-31 22:34:00 +0000245#endif // LLD_READER_WRITER_NATIVE_FILE_FORMAT_H_