diff options
| author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
|---|---|---|
| committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 19:28:47 -0800 |
| commit | f6c387128427e121477c1b32ad35cdcaa5101ba3 (patch) | |
| tree | 2aa25fa8c8c3a9caeecf98fd8ac4cd9b12717997 /libdex/DexDataMap.c | |
| parent | f72d5de56a522ac3be03873bdde26f23a5eeeb3c (diff) | |
| download | android_dalvik-f6c387128427e121477c1b32ad35cdcaa5101ba3.tar.gz android_dalvik-f6c387128427e121477c1b32ad35cdcaa5101ba3.tar.bz2 android_dalvik-f6c387128427e121477c1b32ad35cdcaa5101ba3.zip | |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'libdex/DexDataMap.c')
| -rw-r--r-- | libdex/DexDataMap.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/libdex/DexDataMap.c b/libdex/DexDataMap.c new file mode 100644 index 000000000..a9d429e18 --- /dev/null +++ b/libdex/DexDataMap.c @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2008 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. + */ + +/* + * Verification-time map of data section items + */ + +#include "DexDataMap.h" +#include <safe_iop.h> +#include <stdlib.h> + +/* + * Allocate and initialize a DexDataMap. Returns NULL on failure. + */ +DexDataMap* dexDataMapAlloc(u4 maxCount) { + /* + * Allocate a single chunk for the DexDataMap per se as well as the + * two arrays. + */ + size_t size = 0; + DexDataMap* map = NULL; + + /* + * Avoiding pulling in safe_iop for safe_iopf. + */ + if (!safe_mul(&size, maxCount, sizeof(u4) + sizeof(u2)) || + !safe_add(&size, size, sizeof(DexDataMap))) { + return NULL; + } + + map = malloc(size); + + if (map == NULL) { + return NULL; + } + + map->count = 0; + map->max = maxCount; + map->offsets = (u4*) (map + 1); + map->types = (u2*) (map->offsets + maxCount); + + return map; +} + +/* + * Free a DexDataMap. + */ +void dexDataMapFree(DexDataMap* map) { + /* + * Since everything got allocated together, everything can be freed + * in one fell swoop. Also, free(NULL) is a nop (per spec), so we + * don't have to worry about an explicit test for that. + */ + free(map); +} + +/* + * Add a new element to the map. The offset must be greater than the + * all previously added offsets. + */ +void dexDataMapAdd(DexDataMap* map, u4 offset, u2 type) { + assert(map != NULL); + assert(map->count < map->max); + + if ((map->count != 0) && + (map->offsets[map->count - 1] >= offset)) { + LOGE("Out-of-order data map offset: 0x%x then 0x%x\n", + map->offsets[map->count - 1], offset); + return; + } + + map->offsets[map->count] = offset; + map->types[map->count] = type; + map->count++; +} + +/* + * Get the type associated with the given offset. This returns -1 if + * there is no entry for the given offset. + */ +int dexDataMapGet(DexDataMap* map, u4 offset) { + assert(map != NULL); + + // Note: Signed type is important for max and min. + int min = 0; + int max = map->count - 1; + u4* offsets = map->offsets; + + while (max >= min) { + int guessIdx = (min + max) >> 1; + u4 guess = offsets[guessIdx]; + + if (offset < guess) { + max = guessIdx - 1; + } else if (offset > guess) { + min = guessIdx + 1; + } else { + // We have a winner! + return map->types[guessIdx]; + } + } + + // No match. + return -1; +} + +/* + * Verify that there is an entry in the map, mapping the given offset to + * the given type. This will return true if such an entry exists and + * return false as well as log an error if not. + */ +bool dexDataMapVerify(DexDataMap* map, u4 offset, u2 type) { + int found = dexDataMapGet(map, offset); + + if (found == type) { + return true; + } + + if (found < 0) { + LOGE("No data map entry found @ 0x%x; expected %x\n", + offset, type); + } else { + LOGE("Unexpected data map entry @ 0x%x: expected %x, found %x\n", + offset, type, found); + } + + return false; +} |
