blob: ebc26ea780b9d4413e70f91cee34286930c63d00 [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
Rui Ueyama014192db2013-11-15 03:09:26 +000010#ifndef LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
11#define LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H
Nick Kledzik55fd6be2012-01-16 22:03:44 +000012
Rui Ueyama86f32f42013-11-19 03:48:23 +000013#include <cstdint>
14
Michael J. Spencer9f91f952012-03-09 05:27:11 +000015#include "llvm/Support/DataTypes.h"
Nick Kledzik55fd6be2012-01-16 22:03:44 +000016
17namespace lld {
18
Nick Kledzik55fd6be2012-01-16 22:03:44 +000019//
20// Overview:
21//
22// The number one design goal of this file format is enable the linker to
Michael J. Spencer765792d2012-04-03 18:40:27 +000023// read object files into in-memory Atom objects extremely quickly.
24// The second design goal is to enable future modifications to the
25// Atom attribute model.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000026//
Michael J. Spencer765792d2012-04-03 18:40:27 +000027// The llvm native object file format is not like traditional object file
Nick Kledzik55fd6be2012-01-16 22:03:44 +000028// formats (e.g. ELF, COFF, mach-o). There is no symbol table and no
Michael J. Spencer765792d2012-04-03 18:40:27 +000029// sections. Instead the file is essentially an array of archived Atoms.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000030// It is *not* serialized Atoms which would require deserialization into
31// in memory objects. Instead it is an array of read-only info about each
32// Atom. The NativeReader bulk creates in-memory Atoms which just have
33// an ivar which points to the read-only info for that Atom. No additional
34// processing is done to construct the in-memory Atoms. All Atom attribute
Michael J. Spencer765792d2012-04-03 18:40:27 +000035// getter methods are virtual calls which dig up the info they need from the
Nick Kledzik55fd6be2012-01-16 22:03:44 +000036// ivar data.
Michael J. Spencer765792d2012-04-03 18:40:27 +000037//
Nick Kledzik55fd6be2012-01-16 22:03:44 +000038// To support the gradual evolution of Atom attributes, the Atom read-only
39// data is versioned. The NativeReader chooses which in-memory Atom class
40// to use based on the version. What this means is that if new attributes
41// are added (or changed) in the Atom model, a new native atom class and
42// read-only atom info struct needs to be defined. Then, all the existing
43// native reader atom classes need to be modified to do their best effort
44// to map their old style read-only data to the new Atom model. At some point
Michael J. Spencer765792d2012-04-03 18:40:27 +000045// some classes to support old versions may be dropped.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000046//
47//
48// Details:
49//
Michael J. Spencer765792d2012-04-03 18:40:27 +000050// The native object file format consists of a header that specifies the
Nick Kledzik55fd6be2012-01-16 22:03:44 +000051// endianness of the file and the architecture along with a list of "chunks"
52// in the file. A Chunk is simply a tagged range of the file. There is
Michael J. Spencer765792d2012-04-03 18:40:27 +000053// one chunk for the array of atom infos. There is another chunk for the
54// string pool, and another for the content pool.
Nick Kledzik55fd6be2012-01-16 22:03:44 +000055//
56// It turns out there most atoms have very similar sets of attributes, only
57// the name and content attribute vary. To exploit this fact to reduce the file
58// size, the atom read-only info contains just the name and content info plus
59// a reference to which attribute set it uses. The attribute sets are stored
60// in another chunk.
61//
62
63
64//
65// An entry in the NativeFileHeader that describes one chunk of the file.
66//
67struct NativeChunk {
68 uint32_t signature;
69 uint32_t fileOffset;
70 uint32_t fileSize;
71 uint32_t elementCount;
72};
73
74
75//
76// The header in a native object file
77//
78struct NativeFileHeader {
79 uint8_t magic[16];
80 uint32_t endian;
81 uint32_t architecture;
82 uint32_t fileSize;
83 uint32_t chunkCount;
Nick Kledzik49d6cc82012-02-15 00:38:09 +000084 // NativeChunk chunks[]
Nick Kledzik55fd6be2012-01-16 22:03:44 +000085};
86
87//
88// Possible values for NativeChunk.signature field
89//
90enum NativeChunkSignatures {
91 NCS_DefinedAtomsV1 = 1,
92 NCS_AttributesArrayV1 = 2,
Sid Manning2a590242012-10-18 17:16:19 +000093 NCS_AbsoluteAttributesV1 = 12,
Nick Kledzik23384e82012-02-07 02:59:54 +000094 NCS_UndefinedAtomsV1 = 3,
Nick Kledzik6bc04c62012-02-22 21:56:59 +000095 NCS_SharedLibraryAtomsV1 = 4,
96 NCS_AbsoluteAtomsV1 = 5,
97 NCS_Strings = 6,
98 NCS_ReferencesArrayV1 = 7,
99 NCS_ReferencesArrayV2 = 8,
100 NCS_TargetsTable = 9,
101 NCS_AddendsTable = 10,
102 NCS_Content = 11,
Michael J. Spencer765792d2012-04-03 18:40:27 +0000103};
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000104
105//
106// The 16-bytes at the start of a native object file
107//
108#define NATIVE_FILE_HEADER_MAGIC "llvm nat obj v1 "
109
110//
111// Possible values for the NativeFileHeader.endian field
112//
113enum {
114 NFH_BigEndian = 0x42696745,
115 NFH_LittleEndian = 0x4574696c
116};
117
118
119//
120// Possible values for the NativeFileHeader.architecture field
121//
122enum {
123 NFA_x86 = 1,
124 NFA_x86_64 = 2,
125 NFA_armv6 = 3,
126 NFA_armv7 = 4,
127};
128
129
130//
131// The NCS_DefinedAtomsV1 chunk contains an array of these structs
132//
133struct NativeDefinedAtomIvarsV1 {
134 uint32_t nameOffset;
135 uint32_t attributesOffset;
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000136 uint32_t referencesStartIndex;
137 uint32_t referencesCount;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000138 uint32_t contentOffset;
139 uint32_t contentSize;
140};
141
142
143//
144// The NCS_AttributesArrayV1 chunk contains an array of these structs
145//
146struct NativeAtomAttributesV1 {
147 uint32_t sectionNameOffset;
148 uint16_t align2;
149 uint16_t alignModulus;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000150 uint8_t scope;
151 uint8_t interposable;
152 uint8_t merge;
153 uint8_t contentType;
Nick Kledzik36293f62013-01-23 22:32:56 +0000154 uint8_t sectionChoiceAndPosition; // high nibble is choice, low is position
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000155 uint8_t deadStrip;
Michael J. Spencerb8ab9f52013-11-08 21:04:20 +0000156 uint8_t dynamicExport;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000157 uint8_t permissions;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000158 uint8_t alias;
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000159};
160
161
162
Nick Kledzik23384e82012-02-07 02:59:54 +0000163//
164// The NCS_UndefinedAtomsV1 chunk contains an array of these structs
165//
166struct NativeUndefinedAtomIvarsV1 {
167 uint32_t nameOffset;
168 uint32_t flags;
Rui Ueyamae5416ec2013-09-12 19:14:05 +0000169 uint32_t fallbackNameOffset;
Nick Kledzik23384e82012-02-07 02:59:54 +0000170};
171
172
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000173//
174// The NCS_SharedLibraryAtomsV1 chunk contains an array of these structs
175//
176struct NativeSharedLibraryAtomIvarsV1 {
Michael J. Spencer4355bb92013-09-26 22:08:43 +0000177 uint64_t size;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000178 uint32_t nameOffset;
179 uint32_t loadNameOffset;
Michael J. Spencer4355bb92013-09-26 22:08:43 +0000180 uint32_t type;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000181 uint32_t flags;
182};
183
184
185
186//
187// The NCS_AbsoluteAtomsV1 chunk contains an array of these structs
188//
189struct NativeAbsoluteAtomIvarsV1 {
190 uint32_t nameOffset;
Sid Manning2a590242012-10-18 17:16:19 +0000191 uint32_t attributesOffset;
Nick Kledzik6bc04c62012-02-22 21:56:59 +0000192 uint32_t reserved;
193 uint64_t value;
194};
195
196
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000197
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000198//
199// The NCS_ReferencesArrayV1 chunk contains an array of these structs
200//
201struct NativeReferenceIvarsV1 {
Nick Kledzikb334be12012-04-07 01:31:00 +0000202 enum {
Rui Ueyama86f32f42013-11-19 03:48:23 +0000203 noTarget = UINT16_MAX
Nick Kledzikb334be12012-04-07 01:31:00 +0000204 };
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000205 uint16_t offsetInAtom;
206 int16_t kind;
207 uint16_t targetIndex;
208 uint16_t addendIndex;
209};
210
211
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000212//
213// The NCS_ReferencesArrayV2 chunk contains an array of these structs
214//
215struct NativeReferenceIvarsV2 {
Rui Ueyamae05b6292013-11-20 20:54:18 +0000216 enum {
217 noTarget = UINT32_MAX
218 };
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000219 uint64_t offsetInAtom;
220 int64_t addend;
221 int32_t kind;
222 uint32_t targetIndex;
223};
224
225
226//
227// The NCS_TargetsTable chunk contains an array of uint32_t entries.
Michael J. Spencer765792d2012-04-03 18:40:27 +0000228// The C++ class Reference has a target() method that returns a
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000229// pointer to another Atom. We can't have pointers in object files,
230// so instead NativeReferenceIvarsV1 contains an index to the target.
Michael J. Spencer765792d2012-04-03 18:40:27 +0000231// The index is into this NCS_TargetsTable of uint32_t entries.
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000232// The values in this table are the index of the (target) atom in this file.
233// For DefinedAtoms the value is from 0 to NCS_DefinedAtomsV1.elementCount.
234// For UndefinedAtoms the value is from NCS_DefinedAtomsV1.elementCount to
235// NCS_DefinedAtomsV1.elementCount+NCS_UndefinedAtomsV1.elementCount.
236//
237
238
239//
240// The NCS_AddendsTable chunk contains an array of int64_t entries.
241// If we allocated space for addends directly in NativeReferenceIvarsV1
242// it would double the size of that struct. But since addends are rare,
243// we instead just keep a pool of addends and have NativeReferenceIvarsV1
Michael J. Spencer765792d2012-04-03 18:40:27 +0000244// (if it needs an addend) just store the index (into the pool) of the
Nick Kledzik49d6cc82012-02-15 00:38:09 +0000245// addend it needs.
246//
247
Nick Kledzik55fd6be2012-01-16 22:03:44 +0000248
249
250} // namespace lld
251
Rui Ueyama014192db2013-11-15 03:09:26 +0000252#endif // LLD_READER_WRITER_NATIVE_NATIVE_FILE_FORMAT_H