You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
100 lines
4.8 KiB
100 lines
4.8 KiB
/*
|
|
* Copyright (C) 2016 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.
|
|
*/
|
|
|
|
#ifndef _APP_RELOC_FORMAT_H_
|
|
#define _APP_RELOC_FORMAT_H_
|
|
|
|
|
|
/*
|
|
* INTRODUCTION
|
|
*
|
|
* This is the relocation format we use for Cortex-M4F cpu. This format is
|
|
* consistent with what GCC will produce with our app-compilation flags. So
|
|
* what will it produce? Relocs will ONLY be in RAM, always be word-sized,
|
|
* always be word-aligned, and never overlap. We use all of that. How do we
|
|
* encode? The relocs format is a bytestream. The decoder is conceptually two
|
|
* passes, though it can easily be implemented as a single pass. The first pass
|
|
* unpacks the bytestream into a list of TOKENS and NUMBERS. The second then
|
|
* uses those to reconstruct the list of relocs.
|
|
*
|
|
*
|
|
* PASS #1 - unpacking
|
|
*
|
|
* Each iteration, it will read a byte from the input byte stream, until none
|
|
* are available. This first byte will tell it what to do next. All values that
|
|
* are <= MAX_8_BIT_NUM, are put directly as a NUMBER into the output list.
|
|
* The remaining possibly values all require special handling, which will be
|
|
* described now:
|
|
* TOKEN_32BIT_OFST: 4 bytes follow. They are to be treated as a single
|
|
* 32-bit little-endian value. This value is put into
|
|
* the output list directly as a NUMBER.
|
|
* TOKEN_24BIT_OFST: 3 bytes follow. They are to be treated as a single
|
|
* 24-bit little-endian value. MAX_16_BIT_NUM is added
|
|
* to it, then this value is put into the output list
|
|
* as a NUMBER.
|
|
* TOKEN_16BIT_OFST: 2 bytes follow. They are to be treated as a single
|
|
* 16-bit little-endian value. MAX_8_BIT_NUM is added
|
|
* to it, then this value is put into the output list
|
|
* as a NUMBER.
|
|
* TOKEN_CONSECUTIVE: 1 byte follows. It is read, MIN_RUN_LEN is added to
|
|
* it. That many zero-valued NUMBERS are added to the
|
|
* output list.
|
|
* TOKEN_RELOC_TYPE_CHG: 1 byte follows. It is read, one is added to it, and
|
|
* a TYPE_CHANGE token with that value is added to the
|
|
* output list.
|
|
* TOKEN_RELOC_TYPE_NEXT: a TYPE_CHANGE token with a value of 1 is added to
|
|
* the output list.
|
|
*
|
|
*
|
|
* PASS #2 - decoding
|
|
*
|
|
* The decoder is stateful. Initially the decoder state is representable as:
|
|
* {reloc_type: 0, ofst: 0}. The decoder will work by removig one item at a
|
|
* time from the head of the list generated by PASS #1, and acting on it, until
|
|
* no more exist. It will produce {reloc_type, reloc_offset} tuples, which can
|
|
* then be used to perform actual relocations. Unpon reading a TYPE_CHANGE
|
|
* token, "reloc_type" in the decoder's state shall be incremented by the value
|
|
* the token carries, and "ofst" shall be set to zero. Upon reading a NUMBER,
|
|
* the decoder shall:
|
|
* a. calculate t = "ofst" + (that NUMBER's value) * 4
|
|
* b. store t + 4 into "ofst"
|
|
* c. produce an output tuple {"reloc_type", t}
|
|
*
|
|
*
|
|
* At the end of these two passes a list of tuples exists that has all reloc types
|
|
* and offsets. this list can be easily walked and relocations performed.
|
|
*/
|
|
|
|
|
|
|
|
//offset is always from previous reloc's NEXT word!
|
|
#define TOKEN_RELOC_TYPE_NEXT 0xFF // reloc type changed to previous + 1
|
|
#define TOKEN_RELOC_TYPE_CHG 0xFE // reloc type changed (followed by a byte represeting "reloc_type" increment minus 1)
|
|
#define TOKEN_CONSECUTIVE 0xFD // followed by 8-bit number of directly following words to relocate (in addition to the one we relocated using previous reloc) minus 3 (2 is break-even point)
|
|
#define TOKEN_16BIT_OFST 0xFC // followed by 16-bit x, such that the value we want to represent is x + MAX_8_BIT_NUM
|
|
#define TOKEN_24BIT_OFST 0xFB // followed by 24-bit x, such that the value we want to represent is x + MAX_16_BIT_NUM
|
|
#define TOKEN_32BIT_OFST 0xFA // followed by 32-bit value we want to represent, sent directly
|
|
#define MAX_8_BIT_NUM 0xF9
|
|
#define MAX_16_BIT_NUM (0xFFFF + MAX_8_BIT_NUM)
|
|
#define MAX_24_BIT_NUM (0xFFFFFF + MAX_16_BIT_NUM)
|
|
#define MIN_RUN_LEN 3 //run count does not include first element
|
|
#define MAX_RUN_LEN (0xff + MIN_RUN_LEN)
|
|
|
|
|
|
|
|
|
|
#endif
|