10a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu/* 20a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * Copyright 2011, The Android Open Source Project 30a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * 40a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * Licensed under the Apache License, Version 2.0 (the "License"); 50a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * you may not use this file except in compliance with the License. 60a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * You may obtain a copy of the License at 70a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * 80a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * http://www.apache.org/licenses/LICENSE-2.0 90a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * 100a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * Unless required by applicable law or agreed to in writing, software 110a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * distributed under the License is distributed on an "AS IS" BASIS, 120a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * See the License for the specific language governing permissions and 140a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu * limitations under the License. 150a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu */ 160a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 170a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu#include <stdio.h> 180a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu#include "GOT.h" 190a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 200a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fuvoid *got_symbol_addresses[NUM_OF_GOT_ENTRY]; 210a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fuint got_symbol_indexes[NUM_OF_GOT_ENTRY]; 220a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fusize_t got_symbol_count = 0; 230a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 240a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fuvoid *got_address() 250a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu{ 260a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu return &got_symbol_addresses[0]; 270a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu} 280a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 290a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fuint search_got(int symbol_index, void *addr, uint8_t bind_type) 300a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu{ 310a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu size_t i; 320a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 330a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // For local symbols (R_MIPS_GOT16), we only store the high 16-bit value 340a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // after adding 0x8000. 350a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu if (bind_type == STB_LOCAL) 368d2a1230eae323981b4f6e03406e801a51018432Logan Chien addr = (void *)(((intptr_t)addr + 0x8000) & 0xFFFF0000); 370a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 380a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu for (i = 0; i < got_symbol_count; i++) { 390a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu if (got_symbol_indexes[i] == symbol_index) { 400a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu if (bind_type == STB_LOCAL) { 410a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // Check if the value is the same for local symbols. 420a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // If yes, we can reuse this entry. 430a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // If not, we continue searching. 440a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu if (got_symbol_addresses[i] == addr) { 450a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu return i; 460a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu } 470a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu } 480a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu else { 490a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // The value must be the same for global symbols . 500a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu rsl_assert (got_symbol_addresses[i] == addr 510a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu && "MIPS GOT address error."); 520a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu return i; 530a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu } 540a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu } 550a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu } 560a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu 570a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu // Cannot find this symbol with correct value, so we need to create one 580a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu rsl_assert (got_symbol_count < NUM_OF_GOT_ENTRY && "MIPS GOT is full."); 590a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu got_symbol_indexes[got_symbol_count] = symbol_index; 600a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu got_symbol_addresses[got_symbol_count] = addr; 610a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu got_symbol_count++; 620a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu return (got_symbol_count - 1); 630a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu} 64